优化选择具有数千万条记录和左连接的查询

时间:2015-09-02 13:34:23

标签: sql sql-server tsql

我试图打破过去3天的以下查询但根本无法修改它,因为group by子句在最后。查询将在1小时内执行,返回30K记录,表a包含数千万条记录。所有表都有索引。以下是蒙面查询:

DECLARE @Variable1 VARCHAR(6) = '199101' 

SELECT        
A.Col1,          
'A' as Col2_Name,          
A.Col3,         
B.Col_05,        
A.Col4,          
C.Col_01 AS Col_01_Name,         
SUBSTRING(A.Col5,1,4) AS Col5_Name,          
D.Col_12,     
A.Col6 AS Col6,       
A.Col7,          
SUBSTRING(A.Col8,1,4) AS Col8_Name,          
A.Col9,          
E.Col_01,     
@Variable1 as 'ACC_FROM'          
,@Variable1 AS 'ACC_TO'          
,'' AS [Start_DATE],           
'' AS [End_DATE],         
@Variable1 AS 'PERIOD',          
@Variable1 as Var_Name,          
A.Col10,       
A.Col11,       
SUM(A.Col12) AS 'A1',          
0 AS 'B1',          
0 AS 'C1',          
0 AS 'D1',          
0 AS 'E1',          
0 AS 'F1',          
SUM(A.Col12) AS 'TOTAL'   

FROM TableA A         
LEFT JOIN TableB B ON A.Col3 = B.Col_3 and B.Col_11=A.Col11 AND B.Col_13=A.Col13 AND A.Col1 = B.Col1 and A.Col7 = B.Col_7
LEFT JOIN TableC C ON A.Col4 = LTRIM(RTRIM(C.Col_04))           
LEFT JOIN TableD D ON SUBSTRING(A.Col5,1,4) = SUBSTRING(D.Col_05,1,4) and A.Col1 = D.Col_01 and A.Col7 = D.Col_07          
LEFT JOIN TableE E ON A.Col9 = E.Col_09   

WHERE A.Col14 = 2          
AND A.Col15 = 'C'          
AND A.Col16 <= @Variable1    

GROUP BY           
A.Col1,          
A.Col3,          
B.Col_05,         
A.Col4,          
C.Col_01,         
SUBSTRING(A.Col5,1,4),          
D.Col_12,       
A.Col6,
A.Col7,          
SUBSTRING(A.Col8,1,4),          
A.Col9,          
E.Col_01,  
A.Col10,    
A.Col11

HAVING SUM(A.Col12)<>0  

任何人都可以帮我打破查询,这可以缩短执行时间吗?

1 个答案:

答案 0 :(得分:2)

您收到了很多评论并提出了很好的建议。我将更详细地介绍其中的一些内容。

执行计划 如果您通常被困为只读用户(就像我组织中的那样),那么获取查询执行计划(并了解它们!)可能会很困难。要解决您的权限级别,最简单的方法是获取数据库的副本并将其安装在您具有完全权限的本地计算机上。在那里你可以调整你的查询并尝试不同的东西。在您的计算机上保留数据库的副本(并保证它们的安全性,我可能会添加)将允许您以不一致的方式消除可能影响查询性能的任何网络问题的影响。

搜索ARGuments 其中一条评论提到了非SARGable谓词。您可以找到有关这些here的更多信息。您不会相信遵循本文的指南可能会对您的查询的效果产生影响!

<强>索引 在索引方面,您说所有适当的索引都已到位。如果这是真的并且您知道您的索引没有比它们更好,请忽略本段的其余部分。如果您不是100%确定您需要的所有内容,请查看this,因为它有一些非常干燥但有用的索引信息。 Here对同一主题更容易阅读(但不太全面)。

具体建议 查看您的查询,您将分组并加入表达式的结果。这样做可能非常费力,特别是当涉及数百万条记录时。在这种情况下,在开始应用需要大量处理能力的更具体的过滤器之前,最好先过滤掉尽可能多的不良记录。修复?获取一些更简单的连接并使用临时表中的连接开始使用较小的记录集进行过滤。在临时表中,您还可以创建表示您在分组和连接语句中使用的这些表达式的结果的字段。例如,您可以在临时表中使用col_04(即col_04_trimmed)的修剪副本以及Col5的前四个字符(Col5_first_4)。临时表需要更多的前期处理来构建,但是一旦构建它们,您可以经常查询和处理它们的内容,速度远远快于大量数据的动态操作。完成查询后,请删除临时表并开展业务。

此外,如果您有一个始终表示数字的变量,请将其存储为数字(整数,浮点数等)变量。它会在隐式转换上节省一点时间,特别是在数百万行中。

最后,你说

Having SUM(A.Col12)<>0

而是尝试

Having SUM(A.Col12) > 0

我希望这有帮助!

相关问题