I have SQL query like
SELECT *, dbo.func(@param1, a.point) as fValue
FROM dbo.table AS a
WHERE dbo.func(@param1, a.point) < @param2
When this query is executed only once, everything is fine, but when I have array of input @param1 values let's say, over 100 values, executing and fetching results for every value take s a lot of time.
Is it possible to pass array of @param1 into the query somehow, and receive dataset for all the input values, instead of executing it for each value?
function func() doing some math on 2 values. @param1 and a.point are type of double. and, yeah, a.point - is not an ID, and it is not a unique value.
I know, it should be really easy, but it looks like I'm missing something.
You still need to execute that function 100 times for each row, right? I don't see any shortcuts here.
If you wanted to get them all at once, you could do
or something like that, but looping through them just seems more efficient to me anyway.
I suppose you could use a cursor to retrieve each
a.point
value once, then act on it 100 times, but that's a lot of coding, and not necessarily a simpler solution.Do you have any indexes on this table? If you have an index on a.point, then you will never hit it using this code, ie will always table scan. This is to do with Search Arguments (you can google this). Example:
If you have table xTable with index on column xColumn, then this:
will never use the index, but this probably will:
So you might need something like this:
What exactly does
dbo.func()
do? Is it possible that you could insert the 100 values into a table structure, and perform that operation on the set of 100 all at once, instead of 1x1 100 times?As an example, let's say you have this function, which just turns a comma-separated list of float values into a single-column table:
Now you should be able to get your floats in a set by simply saying:
Taking that a step further, let's say
dbo.func()
takes these two inputs and says something like:Now, I know that you've always been told that modularization and encapsulation are good, but in the case of inline functions, I would suggest you avoid the function that gets this result (again you haven't explained what
dbo.func()
does, so I'm just guessing this will be easy) and do it inline. So instead of callingdbo.func()
- twice for each row, no less - you can just say:The keys are:
Avoiding processing each parameter individually.
Avoiding the individual calculations off in its own separate module.
Performing calculations as few times as possible.
If you can't change the structure this much, then at the very least, avoid calculating the function twice by writing instead:
If you provide details about the data types, what
dbo.func()
does, etc., people will be able to provide more tangible advice.