如何加快此SQL查询的速度

时间:2012-11-05 12:13:12

标签: sql sql-server

我在ASP.NET应用程序中有一段代码,它从参数列表构建SQL查询。参数的数量可以变化,因此可以向此查询添加各种标准。该数据库是Microsoft SQL Server 2008。

所有AND和OR都是以编程方式生成的。

查询执行时间超过3秒,但经过一些分析和索引后,运行时间不到一秒。我仍然认为查询本身可以进行优化。我看过执行计划,但这对我来说并不重要 - 不是SQL大师。

我想知道查询是否可以以更智能的方式完成 - 我无法弄明白。以下是查询示例:

 SELECT [id], [WorkTitle], [CreateDate], [UpdateDate], [Writer], [ValidFrom], 

[ValidTo], [Text] 
 FROM dbo.Texts T  
 WHERE Category_id = 3 AND '2012-11-06' BETWEEN ValidFrom AND ValidTo  
 AND (EXISTS (SELECT 'X' FROM dbo.Criteria_List CL WHERE T.id = CL.Text_id   AND CL.Criteria_id = 1 AND CL.Value = '95068')       
    OR NOT EXISTS (SELECT 'X' FROM dbo.Criteria_List CL WHERE T.id = CL.Text_id AND CL.Criteria_id = 1))  

 AND (EXISTS (SELECT 'X' FROM dbo.Criteria_List CL WHERE T.id = CL.Text_id   AND CL.Criteria_id = 2 AND CL.Value = 'C')       
    OR NOT EXISTS (SELECT 'X' FROM dbo.Criteria_List CL WHERE T.id = CL.Text_id AND CL.Criteria_id = 2))  

 AND (EXISTS (SELECT 'X' FROM dbo.Criteria_List CL WHERE T.id = CL.Text_id   AND CL.Criteria_id = 3 AND CL.Value = 'HEL')       
    OR NOT EXISTS (SELECT 'X' FROM dbo.Criteria_List CL WHERE T.id = CL.Text_id AND CL.Criteria_id = 3))  

 AND (EXISTS (SELECT 'X' FROM dbo.Criteria_List CL WHERE T.id = CL.Text_id   AND CL.Criteria_id = 4 AND CL.Value = 'CC')      
    OR NOT EXISTS (SELECT 'X' FROM dbo.Criteria_List CL WHERE T.id = CL.Text_id AND CL.Criteria_id = 4))  

 AND (EXISTS (SELECT 'X' FROM dbo.Criteria_List CL WHERE T.id = CL.Text_id   AND CL.Criteria_id = 5 AND CL.Value = NULL)     
    OR NOT EXISTS (SELECT 'X' FROM dbo.Criteria_List CL WHERE T.id = CL.Text_id AND CL.Criteria_id = 5))  

 AND (EXISTS (SELECT 'X' FROM dbo.Criteria_List CL WHERE T.id = CL.Text_id   AND CL.Criteria_id = 7 AND CL.Value = '321')      
    OR NOT EXISTS (SELECT 'X' FROM dbo.Criteria_List CL WHERE T.id = CL.Text_id AND CL.Criteria_id = 7))  

 AND (EXISTS (SELECT 'X' FROM dbo.Criteria_List CL WHERE T.id = CL.Text_id   AND CL.Criteria_id = 9 AND CL.Value = 'DK7778')    
    OR NOT EXISTS (SELECT 'X' FROM dbo.Criteria_List CL WHERE T.id = CL.Text_id AND CL.Criteria_id = 9))  

 AND (EXISTS (SELECT 'X' FROM dbo.Criteria_List CL WHERE T.id = CL.Text_id   AND CL.Criteria_id = 10 AND CL.Value = 'TFS')   
    OR NOT EXISTS (SELECT 'X' FROM dbo.Criteria_List CL WHERE T.id = CL.Text_id AND CL.Criteria_id = 10)) 

 AND (EXISTS (SELECT 'X' FROM dbo.Criteria_List CL WHERE T.id = CL.Text_id   AND CL.Criteria_id = 11 AND CL.Value = 'TMP')   
    OR NOT EXISTS (SELECT 'X' FROM dbo.Criteria_List CL WHERE T.id = CL.Text_id AND CL.Criteria_id = 11)) 

 AND (EXISTS (SELECT 'X' FROM dbo.Criteria_List CL WHERE T.id = CL.Text_id   AND CL.Criteria_id = 13 AND CL.Value = 'OY-VKB')   
    OR NOT EXISTS (SELECT 'X' FROM dbo.Criteria_List CL WHERE T.id = CL.Text_id AND CL.Criteria_id = 13)) 

感谢任何提示和技巧。

干杯 延

2 个答案:

答案 0 :(得分:2)

  • 对于表格Texts我会在(Category_id, ValidFrom) INCLUDE (ValidTo)上添加一个索引(如果没有)。 (如果您已经在(Category_id, ValidFrom, ValidTo)(Category_id, ValidFrom)上设置了索引,那么它们也可能非常好。

  • 对于Criteria_List表,(Text_id, Criteria_id, Value)上的索引可能足以让优化器生成一个好的执行计划。

    第二个选项(或者更好的是,您必须使用表大小和分布测试执行计划和运行时间)将是两个索引,一个在(Criteria_id, Text_id)上,一个在{{1}上}。


你可以重写这样的10个条件 - 但是无论如何都应该注意索引:

(Criteria_id, Value, Text_id)

答案 1 :(得分:0)

我建议的一件事是更改数据库设计,以便您可以识别CriteriaList.value记录,而不是按原样列出它们。这将使您的查询更加灵活,意味着您应该能够摆脱存在/不存在的所有或大部分内容,并且可能会加快您的查询速度。

相关问题