【问题标题】:how to solve slow running TSQL query如何解决运行缓慢的 SQL 查询
【发布时间】:2014-06-20 09:10:26
【问题描述】:

我遇到了运行缓慢的查询的问题。 我已经使用 sql server profiler 分析了查询,但似乎找不到一个好的解决方案。 我确实找到了为什么它运行缓慢。如果询问完整数据集,它会在 10 秒内返回 150 行,如果我添加总和和计算,它会返回 18 行,但需要 8 分钟。

在 sql server profiler 中,我发现完整的数据集进行了大约 1 000 000 次读取,而 sum 查询大约为 82 000 000。但我不知道他如何或为什么会获得一些记录。因为完整的数据集是 sum 查询的子选择。

下面的查询是一个例子,不是真正的查询(真正的查询在子查询中也有 union all's 但 sum 查询基本相同)

SELECT Sum(x) * 0.1,
       Sum(y),
       a
FROM   (SELECT x,
               y
        FROM   tx
        INNER JOIN ty ON tx.a = ty.a 
        WHERE  x = 1 --this returns 150 rows in 10s 
       ) sub 
GROUP  BY a -- sum returns 18row 8min 

有人可以帮我做一些我必须做的测试或可以测试的解决方案吗?

【问题讨论】:

  • 显示您的查询计划。
  • 究竟什么是a 在外部查询中引用,因为您的子查询不输出a
  • 我建议您尝试摆脱您在该执行计划中看到的Table Scans 和Index Scans,最昂贵的操作似乎在右上角(粗箭头)。如果您的搜索条件不够具体,引擎需要解析所有行,就会发生扫描——这就是它变得昂贵的原因。你有tx.xtx.aty.a 的索引吗? (如果是,请包括这些代码)这是我开始寻找并尝试创建新索引以帮助加快这些查询(或重写查询以满足您现有的索引)的地方
  • 您发布的示例不是真正的查询。该示例甚至不是有效的语法。然后你发布真实查询的查询计划。从中,您希望如何帮助解决实际查询的性能问题?
  • 如何测试语法无效的查询?您不可能知道该查询与实际查询具有相同的性能问题,因为该查询甚至没有运行。

标签: sql sql-server tsql


【解决方案1】:

尝试使用临时表将查询分解为 2 个步骤以删除子查询:

-- populate temp table
SELECT x, y, a
INTO #TEMP
FROM   tx INNER JOIN ty ON tx.a = ty.a 
WHERE  x = 1

-- query the temp table
SELECT Sum(x) * 0.1,
       Sum(y),
       a
FROM #TEMP
GROUP BY a

【讨论】:

    【解决方案2】:

    我建议进行两次聚合。在您的示例中,这看起来有点荒谬,但结构是:

    SELECT sum(x), sum(y)
           Sum(y),
           a
    FROM   (SELECT a, sum(x) * 0.1 as x, sum(y) as y
            FROM tx INNER JOIN
                 ty
                 ON tx.a = ty.a 
            WHERE  x = 1 --this returns 150 rows in 10s 
            GROUP BY a
           ) sub 
    GROUP  BY a ;
    

    SQL 在聚合单个表、组合结果和重新聚合方面应该比聚合单个表的union 做得更好。此外,如果您使用union 而不是union all,则会影响性能。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-04-01
      • 2018-01-15
      • 1970-01-01
      • 1970-01-01
      • 2021-05-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多