所以,我有一个类似于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分支,因为它会使它再次变快。好像它没有加入另一个减缓查询速度的表,但实际的字符串比较...我很遗憾为什么这么慢,或者我怎么能加快它...任何建议都会不胜感激!
答案 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
上的某些东西可能不会受到伤害。STATUS
和DEPARTMENT_ID
总是相同的话),您可能可以将潜在的新索引构建为Filtered Indexes。< / LI>
IsNewOrBranch
或IsStatusNot107
(两个有些令人震惊的步骤,但可以工作的东西)。或者可能提前预先聚合内部查询中的数据。GROUP BY
变得有点困难。可能有办法避免必须做两个分组。GROUP BY
。虽然这种方法并不总是有用,但有很多次尝试将所有工作塞入单个查询中实际上最终会比几个单独的,简单的优化步骤更糟糕。答案 2 :(得分:0)
您的SQL很好,使用额外的AND子句限制数据通常不会使它变慢。
实际上,选择快速执行路径是一个难题,而SQL Server有时(虽然很少)弄错了。
如何帮助SQL Server找到最佳执行路径: