0

我正在创建一个报告,为此我编写了 2 种不同类型的查询。但是我看到这两种方法之间存在巨大的性能差异。可能是什么原因?我的主表(假设表 A)包含一个日期列。我正在根据日期过滤数据。大约 10 个表连接我与这张表有关。

第一种方法:

select A.id,A1.name,...
from table A
join A1
join A2 ....A10
where A.Cdate >= @date
and A.Cdate <= @date

第二种方法:

With CTE as(select A.id from A where A.Cdate>=@date and A.Cdate<=@date)
select CTE.id, A1.name,.... from CTE join A1 join A2....A10

这里第二种方法很快。是什么原因?在第一种方法中,仅 A 的过滤数据将与其他表数据连接,对吗?

4

3 回答 3

1

执行计划肯定会告诉我们,但如果 CTE 能够在连接之前过滤掉很多行,则可能选择了更优化的连接方法(例如合并而不是哈希)。SQL 不应该以这种方式工作——理论上这两者应该以相同的方式执行。但在实践中,我们发现 SQL Server 的优化器并不完美,并且可以根据各种因素以不同的方式进行调整,包括统计信息、选择性、并行性、缓存中该计划的预先存在版本等。

于 2012-07-21T14:51:36.040 回答
1

一个建议。你应该能够自己回答这个问题,因为你有两个计划。你比较过这两个计划吗?那些相似吗?另外,当性能很差时,您是什么意思,是时间还是 CPU 时间或 IO,或者您比较了什么?

因此,在您发布任何问题之前,您应该检查这些计数器,我相信他们会在大多数情况下提供某种答案。

CTE 用于管理代码,它不会自动提高查询的性能。CTE 将由优化器扩展,因此在您的情况下,这两者在转换或扩展后应该具有相同的查询,因此具有相似的计划。

于 2012-07-21T14:52:38.730 回答
0

CTE 基本上是用于处理更复杂的代码(无论是递归还是具有子查询),但您需要检查执行计划以改进 2 个不同的查询。您可以在以下位置检查 CTE 的使用:http: //msdn.microsoft.com/en-us/library/ms190766 (v=sql.105).aspx

请注意,在许多情况下,临时表的性能也比 CTE 更好,因此您也应该尝试使用临时表。
参考:http ://social.msdn.microsoft.com/Forums/en/transactsql/thread/d040d19d-016e-4a21-bf44-a0359fb3c7fb

于 2012-07-21T14:40:08.277 回答