Today I was given the chance to complain that stored procedures are called stored procedures. I’ve never liked that name. I’d much prefer they had been named “compiled queries” because that’s what they are. This led to me having the chance to say that derived tables should have been called “named queries” because that’s what they are.
What’s a derived table? Think of it as a query with a name (hence “named queries”).
I’m not going to build tables and data to illustrate and compare why they are often so much faster than temp tables. Thus I have no schema to compare this example against, and I apologize if I miss something silly and give you an example that doesn’t work. If that happens, just comment on this post and I’ll fix it.
Here’s the set-up: I want to send a mailing to all customers who have purchased in the last 90 days. I will use my customer table and my order table. (My customers have only one address — this post does not attempt to get into the problem of many addresses per customer.)
I’ve seen this done frequently like this:
––create proc stuff deleted for brevity
select distinct CustomerNumber into #RecentOrders from Orders where OrderDate >= DATEADD(dd, -90, GETDATE())
select CustomerName, CustomerAddress, CustomerCity, CustomerState, CustomerZIP
from Customer
inner join #RecentOrders ro
on ro.CustomerNumber = #RecentOrders.CustomerNumber
––end of temp table example
OK, that works. But this works better:
––begin derived table (er, named query) example, mumbo jumbo excluded
select CustomerName, CustomerAddress, CustomerCity, CustomerState, CustomerZIP
from Customer
inner join (select CustomerNumber from Orders where OrderDate >= DATEADD(dd, -90, GETDATE())) as Recent
on Customer.CustomerNumber = Recent.CustomerID
––end example, the named query (er, derived table) is bold
Every time you use a temp table you should carefully consider your options. Might you want a view instead? Or this, a derived table.
I can’t post the example I once sent to my team — it has too much proprietary information. But I once accomplished the same exact task this way that was once done using temp tables. Temp tables took over 9 minutes. Derived, 2.
I can’t explain why it is so much faster. I’m not a hardcore SQL engineer. But I think it has to do with tempdb and disk I/O.
Try it; you’ll like it.