【问题标题】:Why are these two SQL queries so different in efficiency?为什么这两个 SQL 查询在效率上如此不同?
【发布时间】:2021-09-11 06:30:32
【问题描述】:

我必须在实习中使用 SQL,虽然我知道它的要点,但我并没有真正的编程背景,也不知道是什么让代码变得高效等。

查询 #1

SELECT DISTINCT 
    c.[STAT], c.[EVENT], f.[STAT], f.[EVENT]
FROM
    (SELECT *
     FROM 
         (SELECT 
              *, 
              ROW_NUMBER() OVER (PARTITION BY [ID] ORDER BY [PROCDT], [PROCTIME]) AS a
          FROM 
              TABLE) AS b
    ) AS c
LEFT JOIN 
    (SELECT 
         *
     FROM 
         (SELECT 
              *, 
              ROW_NUMBER() OVER (PARTITION BY [ID] ORDER BY [PROCDT], [PROCTIME]) AS d
          FROM 
              TABLE) AS e
         ) AS f ON c.[ID] = f.[ID] AND a = d - 1
ORDER BY 
    c.[STAT], c.[EVENT], f.[STAT], f.[EVENT]

查询 #2

SELECT DISTINCT 
    b.[STAT], b.[EVENT], d.[STAT], d.[EVENT]
FROM
    (SELECT 
         *, 
         ROW_NUMBER() OVER (PARTITION BY [ID] ORDER BY [PROCDT], [PROCTIME]) AS a
     FROM TABLE) AS b
LEFT JOIN 
    (SELECT 
         *, 
         ROW_NUMBER() OVER (PARTITION BY [ID] ORDER BY [PROCDT], [PROCTIME]) AS c
     FROM TABLE) AS d ON b.[ID] = f.[ID] AND a = c - 1
ORDER BY 
    b.[STAT], b.[EVENT], d.[STAT], d.[EVENT]

查询 #1 和 #2 返回相同的结果,这是意料之中的,但查询 #1 的运行时间约为 5 秒,而查询 #2 的运行时间约为 1 分 35 秒。换句话说,第二个查询的运行时间比第一个要长 1.5 分钟,我真的很想知道为什么。

【问题讨论】:

  • 在运行这两个查询之前包括实际的执行计划:CTRL+SHIFT+ALT+M:docs.microsoft.com/en-us/sql/ssms/…
  • 看起来你应该使用 LEAD/LAG 而不是一开始就搞乱连接。您得到不同时间的原因是查询已重新编译,并且计划不同。在SSMS中执行,查看实际执行计划

标签: sql sql-server select subquery left-join


【解决方案1】:

编写此查询的正确方法是使用lead()。我很确定不需要select distinct,所以这就是你想要的:

SELECT stat, event,
       LEAD(stat) OVER (PARTITION BY ID, ORDER BY PROCDT, PROCTIME) as next_stat,
       LEAD(event) OVER (PARTITION BY ID, ORDER BY PROCDT, PROCTIME) as next_event
FROM TABLE t
ORDER BY stat, event;

您编写的两个查询在 SQL Server 中应该是相同的。显然,额外的子查询使优化器感到困惑。您需要了解执行计划才能更好地理解这一点。

【讨论】:

  • 非常感谢!我只需要不重复的,所以我确实需要不同的结果,但这是一个很棒的发现 - 存在像 LEAD() 这样的函数!
猜你喜欢
  • 2012-02-18
  • 1970-01-01
  • 2021-07-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-03-12
  • 1970-01-01
相关资源
最近更新 更多