添加简单的字符串比较时,为什么我的SQL查询变得不成比例地慢?

时间:2017-06-27 14:53:55

标签: sql sql-server

所以,我有一个类似于MSSQL的SQL查询(为了便于阅读而简化):

SELECT ...
FROM (
    SELECT ..., ROUND(SUM(TOTAL_TIME)/86400.0,2) ... 
    FROM MY_DATA
    WHERE STATUS NOT IN (107)
    GROUP BY ...
) q
WHERE q.Tdays > 0
GROUP BY ...   

它工作正常,但我需要与内部查询中的另一个表进行比较,所以我添加了一个左连接并说了比较:

SELECT ...
FROM (
    SELECT ..., ROUND(SUM(TOTAL_TIME)/86400.0,2) ... 
    FROM MY_DATA
    LEFT JOIN OTHER_TABLE ON MY_DATA.ID=OTHER_TABLE.ID //new JOIN
    WHERE STATUS NOT IN (107) AND (DEPARTMENT_ID='SP' OR DEPARTMENT_ID='BL') //new AND branch
    GROUP BY ...
) q
WHERE q.Tdays > 0
GROUP BY ...  

此查询有效,但比之前的查询要慢很多。奇怪的是,在离开JOIN时注释掉WHERE子句的新AND分支,因为它会使它再次变快。好像它没有加入另一个减缓查询速度的表,但实际的字符串比较...我很遗憾为什么这么慢,或者我怎么能加快它...任何建议都会不胜感激!

3 个答案:

答案 0 :(得分:0)

使用INNER JOIN。无论如何,外部联接被WHERE子句撤消:

SELECT ..., ROUND(SUM(TOTAL_TIME)/86400.0,2) ... 
FROM MY_DATA d INNER JOIN
     OTHER_TABLE ot
     ON d.ID = ot.ID //new JOIN
WHERE od.STATUS NOT IN (107) AND DEPARTMENT_ID IN ('SP', 'BL') //new AND branch
GROUP BY ...

IN不应该有所作为;它更容易编写。)

接下来,如果这仍然具有较慢的性能,那么请查看执行计划。这意味着SQL Server可能在JOIN算法上做出了糟糕的决定。通常,我通过禁止嵌套循环连接来解决这个问题,但也可能有其他解决方案。

答案 1 :(得分:0)

很难明确地说明在没有看到执行计划的情况下会加速或加速的事情。此外,了解您需要的速度会影响您可能想要(或不想)考虑采取的步骤。

以下内容有点含糊不清,但是当我想到这一点时,这些是我想到的一些事情。看看执行计划,正如菲利普·库林在这个良好的环节中提出的那样,可以了解痛点的位置,当然,也可以毫不犹豫地采取这些建议。

  • 您可以考虑向其中一个或两个表添加一些索引。执行计划甚至可能会给你一些有用的建议,但在我的头脑中,OTHER_TABLE.DEPARTMENT_ID上的某些东西可能不会受到伤害。
  • 如果您知道那些硬编码的搜索字词(例如STATUSDEPARTMENT_ID总是相同的话),您可能可以将潜在的新索引构建为Filtered Indexes。< / LI>
  • 您可以预先计算部分此类信息,如果它的变化不是那么快,您需要在每次通话时都重新查询。这又回到了你需要多快的速度,因为几乎任何查询都可以添加列或预先填充的查找表,以避免在运行时进行工作。例如,您可以创建一个新的位字段,如IsNewOrBranchIsStatusNot107(两个有些令人震惊的步骤,但可以工作的东西)。或者可能提前预先聚合内部查询中的数据。
  • 我知道您为了我们的利益简化了查询,但这也使得了解子查询的内容以及随后对该子查询执行的GROUP BY变得有点困难。可能有办法避免必须做两个分组。
  • 同样,如果SQL很难确定如何最好地返回数据,那么您可能还会考虑将您正在做的事情分成单独的语句。例如,您可以使用内部查询的结果填充临时表或表变量,然后对其执行后续GROUP BY。虽然这种方法并不总是有用,但有很多次尝试将所有工作塞入单个查询中实际上最终会比几个单独的,简单的优化步骤更糟糕。
  • 正如Gordon Linoff建议的那样,有许多查询提示可以用于诱导执行计划以特定方式执行操作。但要小心,通常那种方式就是疯狂。

答案 2 :(得分:0)

您的SQL很好,使用额外的AND子句限制数据通常不会使它变慢。

实际上,选择快速执行路径是一个难题,而SQL Server有时(虽然很少)弄错了。

如何帮助SQL Server找到最佳执行路径:

  • 确保statistics on your tables are up-to-date
  • 确保SQL Server可以使用“明显合适”的索引。在选择“显示实际执行计划”选项时,SQL Server Management工作室通常会为您提供缺失索引的建议。