【问题标题】:Does Cte in Sql server executed once or each time it is referenced?Sql server中的Cte是执行一次还是每次被引用?
【发布时间】:2019-09-05 13:53:38
【问题描述】:

我有一张假桌子

create table emp
(
  id int,
  name varchar,
  sal int
)

with cte1 as(
select * from emp where name like 'a%'
),  
cte2 as (
select * from cte1 where sal > 100
),
cte3 as (
select * from cte1 where id != 1223
)
select * from cte2
union all
select * from ct3

以这种方式使用 cte 是否保证 cte1、cte2、cte3 只会运行一次?

虽然我可以检查查询计划,但这是否可以保证如果数据发生更改并且下次优化器决定以另一种方式执行此操作时行为不会改变?

【问题讨论】:

  • 每次被引用。
  • 每次被引用。在这种情况下,emp 将被引用两次。 (可以在查询的query plan 中看到)

标签: sql-server common-table-expression


【解决方案1】:

“以这种方式使用 cte 是否保证 cte1、cte2、cte3 将只运行一次?” 不。你在这里的查询不会“运行”一次cte1,它'会运行两次。这可以在查询的query plan 中看到,您可以看到emp 出现了两次。

这是因为,在最终的 SELECT 中,您在最终选择中同时引用了 cte3cte2。这两个都引用cte1,而后者又引用emp。因此,对 cte3cte2 的调用会导致对对象 emp 的 2 次调用。

从技术上讲,如果您愿意,可以将上面的内容重写为下面的内容;这可能会帮助您了解为什么 emp 被引用了两次:

SELECT *
FROM (SELECT *
      FROM (SELECT *
            FROM emp
            WHERE [name] LIKE 'a%') AS cte1
      WHERE sal > 100) AS cte2
UNION ALL
SELECT *
FROM (SELECT *
      FROM (SELECT *
            FROM emp
            WHERE [name] LIKE 'a%') AS cte1
      WHERE id != 1223) AS cte3;

【讨论】:

    猜你喜欢
    • 2013-01-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-19
    • 1970-01-01
    • 2011-02-13
    • 1970-01-01
    相关资源
    最近更新 更多