SQL服务器如何执行交易脚本? (同样的问题需要花费截然不同的时间来执行)

How does SQL Server execute transact script? (Same question takes vastly different time to exec)

我在一家拥有大量 SQL 脚本的大公司工作。这位用户抱怨他的脚本很慢,我开始研究它。 为了找到慢的地方,我将问题分开并 select-insert 到 Temp tables 中,然后在他的实际问题中使用了 Temp tables。

但是,最终结果是,如果我保持温度 tables,问题的执行速度会快得多。

All in one question: Just shy of 20 minutes.
My broken up question: A bit more than 2 minutes.

有显着差异。

好的,所以整个脚本有 940 行长,我在 Temp tables 中输入的每个问题大约有 70-80 行。

我的 Temp table 工作的结果是一个看起来像这样的问题:

with cte_A
as (
   select *
   from #Temp1
   union all
   select *
   from #Temp2
   union all
   select *
   from #Temp3)
   , cte_B
as (select *
    from #Temp4)
   , cte_C
as (select *
    from #Temp5)
   , OB_BL_NotOverdue
as (select *
    from #Temp6)
   , cte_D
as (select *
    from #Temp7)
   , cte_E
as (select *
    from #Temp8
    union all
    select *
    from #Temp9)

SQL question based on the above.

现在原来的问题用完整的 70-80 行问题代替了 select * from #TempX 所以 只有 的区别是代替 70-80 行 SQL 我在问题之前执行 SQL 并执行 select *。 总 运行 时间(创建所有临时 table 和 运行 解决问题)是 2 分钟。所以我在两次执行中都做了完全相同的工作。

我们 运行 正在使用的服务器是 SQL Server 2016(因此不是最新版本)。

谁能解释为什么?

首先CTE没有什么比写代码和做分离更好的了,但是对于引擎来说它就像子查询一样工作。

因此,如果您将所有查询放在 CTE 中,并且如果它们访问相同的表,则可能会混淆 SQL 引擎,然后这将增加 [=20] 的数量=]I/O 读取.

因此,一旦您将这些东西分别存储在 Temporary table 中,数据就会存储在 tempdb 中 SQL 服务器的内存中。因此,对于 SQL 引擎来说,从内存和 tempdb 中读取数据几乎总是比选择一些特定的计划来有效地从磁盘读取数据更容易。