SQL查询花费超过3分钟才能获得100条记录

时间:2012-10-17 06:09:37

标签: sql sql-server sql-server-2008

有人可以告诉我为什么这个查询需要几分钟才能执行?

Select  
   d.DocumentID, d.IsReEfiled, d.IGroupID, d.ITypeID, d.RecordingDateTime, 
   d.IDate, d.InstrumentID, d.DocumentStatusID,ig.Abbreviation as IGroupAbbreviation, 
   u.Username, j.JDAbbreviation, inf.DocumentName,
   it.Abbreviation as ITypeAbbreviation, d.DocumentDate, 
   ds.Abbreviation as DocumentStatusAbbreviation 
From Documents d 
Inner Join IGroupes ig On d.IGroupID = ig.IGroupID 
Left Join ITypes it On d.ITypeID = it.ITypeID 
Left Join Users u On u.UserID = d.UserID 
Left Join DocumentStatuses ds On d.DocumentStatusID = ds.DocumentStatusID 
Left Join InstrumentFiles inf On d.DocumentID = inf.DocumentID                         
Inner Join Jurisdictions j on j.JurisdictionID = d.JurisdictionID 
Where 
    d.DocumentID IN
      (SELECT DocumentID 
       FROM (SELECT ROW_NUMBER() OVER (Order By DocumentID desc) peta_rn, peta_query.* 
             From (Select d.DocumentID
                   From Documents d) as peta_query) peta_paged 
       WHERE peta_rn > 92000 AND peta_rn <= 92100)

子查询:

SELECT DocumentID 
FROM (SELECT 
         ROW_NUMBER() OVER (Order By DocumentID desc) peta_rn, peta_query.* 
      FROM
         (SELECT d.DocumentID
          FROM Documents d) as peta_query) peta_paged 
WHERE peta_rn > 92000 AND peta_rn <= 92100

本身需要0秒,但整个查询需要几分钟,我甚至没有那么多的连接。它几乎不是6-7连接,在我看来不应该产生这么多问题,因为这些所有外键都有索引。任何人都可以提出可能存在的问题吗?

修改

这太棒了。请参阅此查询,该查询在0秒内执行:

Select  d.DocumentID, d.IsReEfiled, d.IGroupID, d.ITypeID, d.RecordingDateTime, 
        d.IDate, d.InstrumentID, d.DocumentStatusID, u.Username, j.JDAbbreviation, inf.DocumentName,
        it.Abbreviation as ITypeAbbreviation, d.DocumentDate, ds.Abbreviation as DocumentStatusAbbreviation 
            From Documents d 
                Inner Join IGroupes ig On d.IGroupID = ig.IGroupID 
                Left Join ITypes it On d.ITypeID = it.ITypeID 
                Left Join Users u On u.UserID = d.UserID  
                Left Join DocumentStatuses ds On d.DocumentStatusID = ds.DocumentStatusID 
                Left Join InstrumentFiles inf On d.DocumentID = inf.DocumentID                         
                Inner Join Jurisdictions j on j.JurisdictionID = d.JurisdictionID 
                    Where d.DocumentID IN
                        (
                            SELECT DocumentID FROM (SELECT 
                                ROW_NUMBER() OVER (Order By DocumentID desc) peta_rn, peta_query.* From 
                                (
                                        Select   d.DocumentID
                                                From Documents d 

                                ) as peta_query) peta_paged WHERE peta_rn>92000 AND peta_rn<=92100
                        )

如您所见,它只是从查询中删除了ig.Abbreviation IGroupAbbreviation,。我一放ig.Abbreviation IGroupAbbreviation,就开始花几分钟。这不是荒谬的高峰吗?你认为这会导致什么?

编辑2:

更奇怪。将Inner Join IGroupes ig更改为Left Join IGroupes ig会在0秒内执行查询。你能否说一下为什么Inner Join会占用几分钟?这是我的问题是SQL服务器中的这个错误吗?现在唯一的事情就是把头撞到墙上。我浪费了4个多小时。

3 个答案:

答案 0 :(得分:1)

试试此版本的查询:

SELECT  DocumentID 
INTO    #temp
FROM    (
        SELECT  ROW_NUMBER() OVER (Order By DocumentID desc) peta_rn
                , d2.DocumentID
        FROM    Documents d2 
        ) peta_paged
WHERE   peta_rn > 92000 AND peta_rn <= 92100

Select  d.DocumentID, d.IsReEfiled, d.IGroupID, d.ITypeID, d.RecordingDateTime, 
        d.IDate, d.InstrumentID, d.DocumentStatusID,ig.Abbreviation as IGroupAbbreviation, u.Username, j.JDAbbreviation, inf.DocumentName,
        it.Abbreviation as ITypeAbbreviation, d.DocumentDate, ds.Abbreviation as DocumentStatusAbbreviation 
            From Documents d 
                Inner Join IGroupes ig On d.IGroupID = ig.IGroupID 
                Left Join ITypes it On d.ITypeID = it.ITypeID 
                Left Join Users u On u.UserID = d.UserID 
                Left Join DocumentStatuses ds On d.DocumentStatusID = ds.DocumentStatusID 
                Left Join InstrumentFiles inf On d.DocumentID = inf.DocumentID                         
                Inner Join Jurisdictions j on j.JurisdictionID = d.JurisdictionID 
                INNER JOIN #temp ON d.DocumentID = #temp.DocumentID

答案 1 :(得分:0)

我只能看到一个问题。根据用户表中有多少条记录,此行将返回所有用户: 左加入用户u on u.UserID = d.UserID

答案 2 :(得分:0)

这看起来像SQL Server查询优化器在超时之前无法评估所有可能的选择并最终选择糟糕的执行计划。通过重新运行查询以向优化器提供另一个镜头,或者通过更改它以便它可以提出一个好的计划,导致您的查询随后立即运行。

我认为最好的办法是查看执行计划,了解所有时间的使用情况,然后查看更改查询的情况,例如:使用查询提示,或更改数据库,例如添加适当的索引。

This post有一些关于SQL Server如何工作的好信息。