Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/84.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在添加索引后提高SQL查询的性能?_Sql_Sql Server_Tsql - Fatal编程技术网

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

如何在添加索引后提高SQL查询的性能?,sql,sql-server,tsql,Sql,Sql Server,Tsql,我正在尝试执行以下sql查询,但执行起来需要22秒。退回的物品数量为554192件。我需要加快速度,并且已经在所有涉及的表中放置了索引 SELECT mc.name AS MediaName, lcc.name AS Country, i.overridedate AS Date, oi.rating,

我正在尝试执行以下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%的步骤。是否有任何方法可以将其降低到一个较低的阈值,或者有任何方法可以提高整个查询的性能


首先,如果这不是存储过程,则将其设置为存储过程。对于SQLServer来说,这是一个非常复杂的问题

其次,我的经验是,“最坏的做法”有时是个好主意。具体来说,我已经能够通过将大型查询拆分为两三个小查询并组合结果来提高性能


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

删除不需要的profiles表,并将WHERE子句更改为

WHERE  PR.profileid = @profileID
batchactionhistory表上有一个左外部联接,但WHERE子句中也有一个条件,将其转换回内部联接。将您的代码更改为:

LEFT OUTER JOIN batchactionhistory bah 
            ON b.id = bah.batchid
           AND bah.batchactionid = 6    
您不需要batches表,因为它用于连接其他可以直接连接的表,并显示您选择的id,该id在其他表中也可用。进行以下更改:

i.batchidid AS BatchNo, 

LEFT OUTER JOIN batchactionhistory bah 
           ON i.batchidid = bah.batchid 
包含大量数据但未编制索引的表中的联接或WHERE子句中使用的任何字段。如果是这样,请尝试在最大的表中添加一个索引


您是否需要结果中的每个字段?如果您可以丢失一个字段或将其删除,您可能会进一步减少表的数量。

尝试查看(或者在某处发布)实际执行计划。另外,我不确定20表联接的运行速度……问题是我需要这些查询能够在report builder 3中运行,但是由于它们运行缓慢,查询生成器会崩溃。老实说,我并不感到意外。您的联接中有20个表。然而,仅仅因为您在“涉及的所有表中”抛出了索引,并不意味着您首先放置了正确的索引,或者您的表设计是合理的。此外,我在您的查询中看到了一些奇怪之处。inner/left/inner/left序列令人费解,而且您是否知道,例如,batchactionhistory上的where子句使内部联接而不是外部联接?我必须使用左外部联接,因为某些列可能有空值,如果使用内部联接,则查询无法返回任何结果。是否有任何地方可以将执行计划上载到xml或图表?