In my past experience, I’ve always used functions in simple cases where I need to select a dataset, without a lot of complex logic, and I need to also pass a parameter.
I’ve recently been informed that I should avoid using functions in MSSQL at all costs, because they often cause performance issues, and sometimes their use causes indexing to not me used properly. Can anyone speak to this point, and explain in further detail if this is true, and some reasoning behind it?
You have been advised naively.
Scalar Functions
WHERE dbo.fn_get_year(tbl.field) = 2012will obfuscatetbl.fieldand make any index on it unusable.You will find much better performance with, for example,
WHERE tbl.field >= '20120101' AND tbl.field < '20130101'.In the first example, every record has to be processed, because the optimiser can’t see through the function and infer which range of records will fit the criteria.
In the second example, you make it very clear you want a continuous block of records from point a to point b. This enables the optimiser to use the index for a range seek.
Table Valued Functions
All of that is very different from
SELECT * FROM dbo.my_function(@parameter) AS data. There is nothing wrong with table valued functions being used in that way.A complexity comes when joining the results of the function to another table or function.
If the function is multi-statement (with
IFblocks, etc, etc) then the whole result set of the function is returned before the join is processed.If the function is an inline-function (with just a
RETURNS TABLE AS SELECT blah FROM blah) then SQL Server treats it as a macro (unless you tell it not to). This means that your function code is substituted into your query, and a brand new execution plan is built for your query. That may mean that only the relevant records from your function are ever processed due to index optimisation, etc.In short, ask the person who advised you to be exceptionally specific about their advice. If it remains
never use functionsjust ignore them.