我正在学习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)
答案 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中,这有三件事 - 其中没有一件与性能有关:
从性能角度来看,SQL Server以完全相同的方式处理非递归CTE和子查询。它们都作为"原始SQL"插入到执行计划中。也就是说,任何一个都没有单独的编译或具体化。据我所知,甚至还没有编译器暗示实现。
CTE通常具有一些优势。您可以在同一查询中多次引用它们,从而提供重用代码的机会。例如,我经常有一个结构,我定义"常数"查询的参数为:with params as (select 'x' as val1)
然后我可以cross join
进入我需要的任何子查询,并且参数只需要更改一次。
CTE可以在没有嵌套的情况下相互引用。这有助于简化查询的外观。
CTE支持递归。
那就是说,我经常同时使用它们。