SQL Server中的派生表VS子查询:优缺点

时间:2015-04-24 15:15:49

标签: sql sql-server

我正在学习SQL Server,并且有兴趣知道在什么情况下决定使用每个概念。我在下面有一个简单的例子,它将返回相同的数据。在现实生活中,我的问题是如何决定使用哪种技术?

select empName
, empTitle
, empID
from (select empName, empTitle, empID from tblManagers) as mgrs

select empName
, empTitle
, empID
from tblEmployees
where empID in (select empID from tblManagers)

2 个答案:

答案 0 :(得分:1)

Sql server是聪明的,所以首先声明:

select empName
, empTitle
, empID
from (select empName, empTitle, empID from tblManagers) as mgrs

转换为:

select empName
, empTitle
, empID
from tblManagers

有一个表扫描。第二个语句产生2个表扫描,然后为运算符执行嵌套循环。因此,第一个声明是赢家听到的。

作为建议,您应该始终检查数据。你应该检查执行计划。更短更好看的陈述并不总是最好的。同一个陈述可以给你不同的数据等不同的结果。这取决于很多事情。

您可以在此处查看三条声明及其执行计划http://sqlfiddle.com/#!6/2f53f/3

答案 1 :(得分:0)

你的两个问题做了不同的事情,所以我不能对它们发表评论。

在SQL Server中,这有三件事 - 其中没有一件与性能有关:

  • 您是否因为使用递归CTE而必须使用CTE?
  • 您是否在代码中多次使用查询逻辑?
  • 您是否偏爱其中一个?

从性能角度来看,SQL Server以完全相同的方式处理非递归CTE和子查询。它们都作为"原始SQL"插入到执行计划中。也就是说,任何一个都没有单独的编译或具体化。据我所知,甚至还没有编译器暗示实现。

CTE通常具有一些优势。您可以在同一查询中多次引用它们,从而提供重用代码的机会。例如,我经常有一个结构,我定义"常数"查询的参数为:

with params as (select 'x' as val1)

然后我可以cross join进入我需要的任何子查询,并且参数只需要更改一次。

CTE可以在没有嵌套的情况下相互引用。这有助于简化查询的外观。

CTE支持递归。

那就是说,我经常同时使用它们。