WITH 语句是每个查询执行一次还是每行执行一次?

2023-12-28

我对WITH语句(CTE)的理解是它每个查询执行一次。通过这样的查询:

WITH Query1 AS ( ... )
SELECT *
FROM
    SomeTable t1
    LEFT JOIN Query1 t2 ON ...

如果这导致 100 行,我预计Query1只被执行了一次——而不是 100 次。如果该假设正确,则运行整个查询所需的时间大致等于以下内容所需的时间:Query1+ 选择SomeTable + join SomeTable to Query1.

我现在的情况是:

  • Query1单独运行大约需要 5 秒(400k 行)。
  • 删除后查询的其余部分WITH声明和LEFT JOIN大约需要 15 秒(400k 行)。

因此,当使用以下命令运行整个查询时WITH声明和LEFT JOIN在适当的位置,我本希望查询能够及时完成,但我让它运行了一个多小时,一旦停止,它最多只能得到 11k 行。

我显然错了,但为什么呢?


Example:

SET NOCOUNT ON;
SET IMPLICIT_TRANSACTIONS ON;

CREATE TABLE MyTable (MyID INT  PRIMARY KEY);
GO
INSERT  MyTable (MyID)
VALUES  (11), (22), (33), (44), (55);

PRINT 'Test MyCTE:';
WITH MyCTE
AS (
    SELECT  *, ROW_NUMBER()OVER(ORDER BY MyID) AS RowNum
    FROM    MyTable
)
SELECT  *
FROM    MyCTE crt
LEFT JOIN MyCTE prev ON crt.RowNum=prev.RowNum+1;

ROLLBACK;

If you run previous script in SSMS (press Ctrl+M -> Actual Execution Plan) then you will get this execution plan for the last query: enter image description here

在这种情况下,CTE 执行一次crt别名和五(!)次prev别名,每行一次crt.

所以,这个问题的答案

WITH 语句是每个查询执行一次还是每行执行一次?

is both:每个查询一次(crt)并且每行一次(prev: 一次对于每个从crt).

为了优化这个查询,首先, 1)您可以尝试存储CTE的结果(MyCTE or Query) 到表变量或临时表中

2)定义该表的主键作为连接列,

3) 重写最终查询以使用此表变量或临时表。

当然,您可以尝试重写最终查询,而无需 CTE 之间的自连接。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

WITH 语句是每个查询执行一次还是每行执行一次? 的相关文章

  • 在 Ruby 中生成 GUID

    我有一个问题 用 GUID 很容易解决 特别是 对于密码重置工作流程 我想将 GUID 令牌发送到用户的电子邮件并让他们使用该令牌重置密码 由于 GUID 是唯一的 因此这非常安全 并且可以避免我通过电子邮件向人们发送密码 这是有风险的 我
  • F# 正确使用序列缓存

    我正在尝试将 Seq cache 与我制作的函数一起使用 该函数返回最多为 N 的素数序列 不包括数字 1 我无法弄清楚如何将缓存的序列保留在范围内 但仍然使用它在我的定义中 let rec primesNot1 n 2 n gt Seq
  • 别名在 Bash 脚本中不起作用[重复]

    这个问题在这里已经有答案了 我有一个可执行文件command sh bin bash alias my command echo ok my command 我的终端是bash 当我像这样运行时 command sh 效果很好 当我像这样运
  • 蓝牙 LE 中步数计数的服务和特性是什么?

    低功耗蓝牙中步数的服务 特征值 UUID 是什么 蓝牙文档的相应页面没有列出任何步骤 如何计算步数 计步设备是否使用跑步速度和步频服务 谢谢 有些设备确实使用跑步速度和节奏服务 您应该能够通过将 总距离 除以 瞬时步长 两者都可以在RSC测
  • 检查一个数是否是完全平方数?

    我认为以下代码存在精度问题 bool isPerfectSquare long long n long long squareRootN long long sqrt n 0 5 return squareRootN squareRootN
  • 强制函数调用的顺序?

    假设我有一个抽象基类 并且我想要一个必须由派生类实现的纯虚方法 但我想确保派生方法以特定顺序调用函数 我可以做什么来强制执行它 I E base class virtual void doABC 0 virtual void A 0 vir
  • 从 Ruby 运行 shell 命令:在显示输出时捕获输出?

    我有个问题 我想从另一个 ruby 脚本运行一个 ruby 脚本并捕获它的输出信息 同时让它也输出到屏幕上 runner usr bin env ruby print Enter your password password gets ch
  • 用于将用户发送至设备应用商店上的应用评论页面的 URL

    为了将 iTunes App Store 置于最前面并打开它以显示应用程序的评论页面 要启动的 URL 是什么 我想将我的用户发送到 撰写评论 页面 其他一些 SO 答案提供了如下 URL 但它似乎不起作用 itms apps itunes
  • 如何在服务器上获取球衣日志?

    我正在使用球衣进行 REST WS 如何在服务器端启用球衣日志 很长的故事 我收到客户端异常 但我在 tomcat 日志中没有看到任何内容 它甚至没有到达我的方法 由于堆栈跟踪显示 toReturnValue 它确实从服务器获取了一些内容
  • JAAS keytab 配置的相对路径

    我有一个系统 其中 NET 客户端使用 Kerberos 针对 Java 服务器进行身份验证 一切正常 但我正在尝试改进服务器配置 目前一个keytab根目录中需要文件C 因为我的jaas配置文件看起来像这样 Server com sun
  • Angular2排序数组用于在html中的*ngFor中显示

    我正在循环浏览所有帖子 li 当显示每个帖子的日期时 我会执行以下操作 post date date yyyy MM dd HH mm ss 我想要做的是按最新的第一个顺序显示所有帖子 我尝试过使用类似的管道 li li import Pi
  • CMake 中的 FindSDL2 发生了什么?

    我在游戏中使用 SDL2 我一直使用自定义 FindSDL2 cmake 因为标准 CMake 集中没有 然而 前段时间确实出现了有关 FindSDL2 的帖子 例子 红迪网帖子 https www reddit com r opengl
  • 从外部material-ui组件访问主题

    我有一个使用标准深色主题的主题提供商 我希望能够从我自己的自定义组件访问该主题的详细信息 但我不知道如何做到这一点 在下面的例子中 this props theme未定义 ReactDOM render
  • 如何在不显示父活动的情况下将一个全屏对话框片段替换为另一个全屏对话框片段?

    我有一个使用单个自定义 DialogFragment 类的活动 它的外观是数据驱动的 因此不同的调用看起来可能相当不同 它是 全屏 即 setStyle DialogFragment STYLE NO FRAME android R sty
  • Google Analytics PHP(发送信息)

    大意 我正在开发一个项目 我需要使用 Google Analytics 服务器端 我不需要检索信息 但我需要发送信息 我最终可以发送 js 脚本客户端 但在这种情况下它不是一个选项 以下大多数链接都非常旧 2012年 检索 不是我需要的 我
  • Apache Flink - “keyBy”中的异常处理

    由于代码错误或缺乏验证 进入 Flink 作业的数据可能会触发异常 我的目标是提供一致的异常处理方式 我们的团队可以在 Flink 作业中使用这种方式 而不会导致生产中出现任何停机 重启策略似乎不适用于此处 因为 简单的重启无法解决问题 我
  • 在哪里放置资源特定逻辑

    您能帮我考虑在 AngularJS 中将资源 服务 特定的业务逻辑放置在哪里吗 我觉得在我的资源上创建一些类似模型的抽象应该很棒 但我不确定如何做 API调用 gt GET customers 1 lt first name John la
  • 如何循环遍历颜色数组以更改按键背景(按下/向下)

    互联网 如果这与其他人没有什么关系 请原谅我 但我会将其留在这里 以防这是一个有效的问题 我正在尝试创建一个文本区域字段 其中用户每次按下键 a z 都会触发背景颜色更改 在数组中列出 我一直在用 JQuery 做这件事 我想我已经很接近了
  • SQL Express 上的 OLAP

    我想知道是否有任何桌面 OLAP 解决方案可以使用 SQL Express 因此不需要 Analysis Services 我的任务是找到一种方法让我们的客户能够制作 临时 报告 但其中绝大多数都是在 Sql Express 上 在以前的工
  • 如何根据当前日期时间发现财政年度?

    我需要基于当前或今天的日期时间的财政年度 假设我们认为今天的日期是10 April 2011 那么我需要输出为Financial Year 2012在某些情况下 我需要以短格式显示相同的输出FY12 我想以两种方式显示 在我们的要求中 考虑

随机推荐