5

I'm writing reports with fairly complex datasets, lots of joins. To simplify matters, and because I'm basically an OO developer, I've been writing little (usually scalar) functions to do the work that could be done by joining onto a subquery. This sort of thing:

SELECT 
    x.Name, x.userId, 
    ... [more columns and joins]
    dbo.CountOrders(x.userId)
FROM Customers x 
WHERE ...

Is this good practice? Sloppy? Slow? Should I be writing regular T-SQL to do this stuff?

Mark Sowul
  • 10,244
  • 1
  • 45
  • 51
immutabl
  • 6,857
  • 13
  • 45
  • 76
  • 1
    Well I'm a DB guy who is now doing OO work, whatdya say we make a trade? Think our employers will mind? – tnktnk Jan 25 '12 at 20:51
  • I'm sure you'll be fine - OO programming will surely be a holiday compared to the archaic nastiness of SQL ;) – immutabl Jan 26 '12 at 09:11

3 Answers3

3

I would pretty much never have a scalar UDF that does data access.

Scalar UDFs can't get expanded out by the optimiser and need to be evaluated RBAR. It is fairly well established that this is not a good idea.

Some example reading.

Community
  • 1
  • 1
Martin Smith
  • 438,706
  • 87
  • 741
  • 845
  • 2
    It's worth noting that the second link addresses this exact question and offers a possible alternative ([inline table-valued UDFs](http://msdn.microsoft.com/en-us/library/ms189294.aspx)). – Cheran Shunmugavel May 25 '11 at 05:08
  • +1 for table-valued UDFs. Looks like I'm going to be re-writing quite a lot of nasty, spidery T-SQL code :-( Thanks for all your responses. – immutabl May 25 '11 at 14:10
  • "I would pretty much never have a scalar UDF that does data access." I'd scratch out "that does data access." Any scalar UDFs in a query, no matter how trivial, will kill its performance. – Mark Sowul Jan 25 '12 at 20:43
  • That's what you get paid the big bucks for :-) – tnktnk Jan 25 '12 at 20:50
0

In my opinion and from my experience inline functions are not necessarily evil. Sometimes i face a task that i couldn't achieve without using functions. If you are reusing the same exact routine over and over again in your stored procedures, then, just like in good old OOP you create a function and use it. But just for the sake of clean and short code I would not recommend using functions, if its one time use. The performance hit or improvement comes from table indexing and index maintenance. As long as the indexes are correctly created and maintained, inline functions are as good as writing plain sql statement.

Dimitri
  • 6,923
  • 4
  • 35
  • 49
0

I don't think there is much harm in doing function call computations in SQL as long as it is clear where they are being done to the users of the table. All you have done here is make a shortcut to a subquery. However, I never do this with my primary access queries as people start to "take for granted" these kinds of computations.

If I find I'm doing this repetitively, I find it more valuable to make a look-aside table that contains this kind of information in a precomputed form and then use triggers to keep it up to date. An example of this is a database where I roll-up the financial summary data from the invoice line-items to the quote level, then again to the submission level (which has multiple quotes) and then again to the policy level (which has multiple trees from multiple carriers).

It turns out that most of the queries really need the data at the policy level. By using triggers and summary tables I sped up some critical queries literally two orders of magnitude simply because the work was already done, while decreasing the performance of a saved change by an inconsequential amount. So if you find yourself doing a lot of summary queries, think about a way to avoid the work... but for simple cases I think inline calls to functions are fine.

Godeke
  • 16,131
  • 4
  • 62
  • 86