1

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

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 igLeft Join IGroupes ig在 0 秒内执行查询。您能否建议为什么 Inner Join 会占用几分钟?这是我的问题,这是 SQL Server 中的一些错误吗?现在唯一剩下的就是用头撞墙。我浪费了4个多小时。

4

3 回答 3

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
于 2012-10-17T06:17:54.423 回答
0

我只能看到一个问题。根据用户表中有多少记录,此行将返回所有用户: Left Join Users u On u.UserID = d.UserID

于 2012-10-17T06:26:02.770 回答
0

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

我认为您最好的选择是查看执行计划以查看所有时间都花在了哪里,然后查看更改您的查询,例如使用查询提示,或更改您的数据库,例如添加适当的索引。

这篇文章有一些关于 SQL Server 如何工作的好信息。

于 2012-10-17T08:21:10.977 回答