MSDN :

与派生的表不同,CTE可以是自我引用,并且可以在同一查询中多次引用。

我经常使用CTE,但是我从未深入考虑使用它们的好处。

如果我在同一查询中多次引用CTE:

  • 有任何性能好处吗?
  • 如果我进行自加入,SQL Server会两次扫描目标表吗?
有帮助吗?

解决方案

通常, CTE永远不会提高性能.

CTE本质上是一次性观点。没有存储的其他统计信息,没有索引等。它可以作为子查询的速记。

我认为,它们很容易被过度使用(我看到工作中的代码过量有很多)。 这里有一些好的答案, 但是,如果您需要多次参考某些东西,或者超过几千行,请将其放入 #temp 桌子并将其索引。

其他提示

除了递归之外,我发现CTE非常有用的地方是创建复杂的报告查询。我使用一系列CTE来获取所需的数据块,然后在最终选择中组合。我发现它们比使用大量派生表或20个连接来进行相同的事情更容易维护所有不同的连接。让我快速举个例子:

;WITH Conferences (Conference_id)
AS 
(select  m.Conference_id
FROM mydb.dbo.Conference m 
WHERE client_id = 10
    and Conference_id in 
            (select Conference_id from mydb.dbo.Expense 
            where amount <>0
            and amount is not null)
     )
--select * from Conferences
,MealEaters(NumberMealEaters, Conference_id, AttendeeType)
AS
(Select count(*) as NumberMealEaters, m.Conference_id,  AttendeeType 
from mydb.dbo.attendance ma 
join Conferences m on m.Conference_id = ma.Conference_id
where (ma.meals_consumed>0 or meals_consumed is null)and attended = 1
group by m.Conference_id)
--select * from MealEaters

,Expenses (Conference_id,expense_date, expenseDescription,  RecordIdentifier,amount)
AS
(select Conference_id,max(expense_date) as Expense_date, expenseDescription,  RecordIdentifier,sum(amount) as amount
    FROM
        (SELECT Conference_id,expense_date,  amount, RecordIdentifier
        FROM mydb.dbo.Expense
        WHERE  amount <> 0 
            and Conference_id IN 
            (SELECT  Conference_id
            FROM mydb.dbo.Conferences ) 
        group by Conference_id, RecordIdentifier) a
)
--select * from Expenses
Select m.Conference_id,me.NumberMealEaters, me.AttendeeType, e.expense_date,         e.RecordIdentifier,amount
from Conferences m
join mealeaters me on m.Conference_id = me.Conference_id
join expenses e on e.Conference_id = m.Conference_id

因此,通过分开所需的不同信息块,您可以单独检查每个部分(使用评论的选择,通过单独删除每个部分,只能运行到选择,并且如果您需要更改为费用计算(在此示例中),与将它们全部混合在一起的一个大量查询时更容易找到。当然,我使用的实际报告查询通常比示例要复杂得多。

与往常一样,这取决于,但在某些情况下,性能得到了极大的改善。我将其视为插入到选择语句中,在其中您将CTE用于选择,然后将其在插入中使用。它可能与为数据库设置的RCSI有关,但是对于那些很少选择的时间,它可以帮助您很多。

许可以下: CC-BY-SA归因
不隶属于 dba.stackexchange
scroll top