如何在添加索引后提高SQL查询的性能?

时间:2013-04-16 11:55:11

标签: sql sql-server tsql

我正在尝试执行以下sql查询,但执行需要22秒。返回项目的数量是554192.我需要更快地完成这项工作,并且已经将索引放在所有涉及的表中。

SELECT mc.name                           AS MediaName, 
       lcc.name                          AS Country, 
       i.overridedate                    AS Date, 
       oi.rating, 
       bl1.firstname + ' ' + bl1.surname AS Byline, 
       b.id                              BatchNo, 
       i.numinbatch                      ItemNumberInBatch, 
       bah.changedatutc                  AS BatchDate, 
       pri.code                          AS IssueNo, 
       pri.name                          AS Issue, 
       lm.neptunemessageid               AS MessageNo, 
       lmt.name                          AS MessageType, 
       bl2.firstname + ' ' + bl2.surname AS SourceFullName, 
       lst.name                          AS SourceTypeDesc 
FROM   profiles P 
       INNER JOIN profileresults PR 
               ON P.id = PR.profileid 
       INNER JOIN items i 
               ON PR.itemid = I.id 
       INNER JOIN batches b 
               ON b.id = i.batchid 
       INNER JOIN itemorganisations oi 
               ON i.id = oi.itemid 
       INNER JOIN lookup_mediachannels mc 
               ON i.mediachannelid = mc.id 
       LEFT OUTER JOIN lookup_cities lc 
                    ON lc.id = mc.cityid 
       LEFT OUTER JOIN lookup_countries lcc 
                    ON lcc.id = mc.countryid 
       LEFT OUTER JOIN itembylines ib 
                    ON ib.itemid = i.id 
       LEFT OUTER JOIN bylines bl1 
                    ON bl1.id = ib.bylineid 
       LEFT OUTER JOIN batchactionhistory bah 
                    ON b.id = bah.batchid 
       INNER JOIN itemorganisationissues ioi 
               ON ioi.itemorganisationid = oi.id 
       INNER JOIN projectissues pri 
               ON pri.id = ioi.issueid 
       LEFT OUTER JOIN itemorganisationmessages iom 
                    ON iom.itemorganisationid = oi.id 
       LEFT OUTER JOIN lookup_messages lm 
                    ON iom.messageid = lm.id 
       LEFT OUTER JOIN lookup_messagetypes lmt 
                    ON lmt.id = lm.messagetypeid 
       LEFT OUTER JOIN itemorganisationsources ios 
                    ON ios.itemorganisationid = oi.id 
       LEFT OUTER JOIN bylines bl2 
                    ON bl2.id = ios.bylineid 
       LEFT OUTER JOIN lookup_sourcetypes lst 
                    ON lst.id = ios.sourcetypeid 
WHERE  p.id = @profileID 
       AND b.statusid IN ( 6, 7 ) 
       AND bah.batchactionid = 6 
       AND i.statusid = 2 
       AND i.isrelevant = 1 

在查看执行计划时,我可以看到一个耗资42%的步骤。有什么方法可以让我达到更低的阈值或任何方式,我可以提高整个查询的性能。

enter image description here

2 个答案:

答案 0 :(得分:2)

删除不需要的配置文件表,并将WHERE子句更改为

WHERE  PR.profileid = @profileID

您在batchactionhistory表上有一个左外连接,但在WHERE子句中也有一个条件将其转回内部连接。将您的代码更改为:

LEFT OUTER JOIN batchactionhistory bah 
            ON b.id = bah.batchid
           AND bah.batchactionid = 6    

您不需要批处理表,因为它用于连接可以直接连接的其他表,并在您的SELECT中显示ID,这也可以在其他表中使用。进行以下更改:

i.batchidid AS BatchNo, 

LEFT OUTER JOIN batchactionhistory bah 
           ON i.batchidid = bah.batchid 

连接中使用的任何字段或包含大量数据但未编制索引的表的WHERE子句。如果是这样,请尝试在最大的表格上添加索引。

你是否需要结果中的每个字段 - 如果你可以松开一个或者你可能会进一步减少表的数量。

答案 1 :(得分:1)

首先,如果这不是存储过程,请将其设为一个。这是sql server要编译的很多文本。

接下来,我的经验是“最糟糕的做法”偶尔也是一个好主意。具体来说,我已经能够通过将大型查询分成几个或三个小查询并汇总结果来提高性能。

如果此查询与.net,coldfusion,java等应用程序相关联,则可以在应用程序代码中进行拆分/重组。如果没有,临时表可能派上用场。