Reputation: 67918
So based off the way I've seen WITH
used, and the documentation at MSDN:
Specifies a temporary named result set, known as a common table expression (CTE).
it appears that the WITH
is the replacement for #TEMP
tables. Is that correct?
Upvotes: 5
Views: 14734
Reputation: 50271
No. CTEs—introduced by WITH
—don't replace temp tables, although in some cases they can be used where one might have used a temp table in the past.
WITH
is really nothing more than a derived table, with the difference that it is introduced before the query instead of inline, and is given an alias which can then be used as a table throughout the query multiple times.
A derived table is a complete query, inside of parentheses, that is used as if it were a real table. Views and table-valued functions are also considered derived tables, but we're focusing on the kind that is defined inline. Here is an example:
SELECT
C.Name,
S.SalesTotal
FROM
dbo.Customer C
INNER JOIN (
SELECT
O.CustomerID,
SalesTotal = Sum(OrderTotal)
FROM
dbo.CustomerOrder O
GROUP BY
O.CustomerID
) S
ON C.CustomerID = S.CustomerID;
We have a completely intact query that returns its own rowset (the GROUP BY
query). By placing this inside of parentheses and assigning it an alias S
, we can now use it like a table. We could join more tables to this one. But, we have only joined to this table once.
To convert this to a CTE, we make a very simple change:
WITH SalesTotals AS (
SELECT
O.CustomerID,
SalesTotal = Sum(OrderTotal)
FROM
dbo.CustomerOrder O
GROUP BY
O.CustomerID
)
SELECT
C.Name,
S.SalesTotal
FROM
dbo.Customer C
INNER JOIN SalesTotals S
ON C.CustomerID = S.CustomerID
-- and for an example of using the CTE twice:
INNER JOIN (
SELECT Avg(SalesTotal)
FROM SalesTotals
) A (AverageSalesTotal)
ON S.SalesTotal >= A.AverageSalesTotal;
Now, a temp table is a completely different animal. It has very important differences from a CTE or derived table:
Avg(SalesTotal)
calculation, in versions of SQL Server through at least 2012, will involve a completely separate operation of performing the SalesTotals
aggregate a second time. While it is possible for the engine to materialize the results of the CTE, so far SQL Server has not done this. It is notable that other DBMSes such as Oracle may materialize the results of a CTE. In any case, you should be aware that this double-querying can have (of course!) serious performance implications.Last, a CTE can do something a temp table cannot: it can be recursive. In Oracle this is expressed through CONNECT BY
, and in SQL Server it is done with a UNION ALL SELECT
inside the CTE that is allowed to refer to the CTE's own alias.
Be careful with CTEs. They are a great abstraction, but are nothing more than that, and you can run into serious trouble with them. Generating a million rows can be done with a recursive CTE one row at a time, but it's the WORST possible way by like a hundred times over or more.
There is another special kind of temp table in SQL Server 2005 and up called a "table variable" that is very much like a temp table (and kept in tempdb exactly the same), with a few notable exceptions:
Upvotes: 19
Reputation: 58
The SQL optimizer does a much better job today at choosing great execution plans, but when joining more than 10 tables, especially with some large tables and views and needing to use multiple filters, it often does not perform optimally. I still find there is nothing as fast as using #TEMP tables and breaking the queries down into much smaller subsets before joining them together. NOTE: it is rare that I find that adding indexes to the #TEMP tables improves performance.
Upvotes: 1
Reputation: 1123
No, that is not correct. They are both separate pieces of functionality and each have their individual uses.
For instance, CTEs are good for small bits of data while temp tables are usually better suited to larger datasets. Temp tables can be indexed and their performance improved whereas CTEs can not.
I would spend a little time reading through the MSDN documentation and looking at particular instances where you would use one or the other
Upvotes: 0