1

DB に約 90,000 のレコードがあり、次のクエリを実行します。

時間がかかりすぎます (約 4 秒):

SELECT * FROM (SELECT 
    ROW_NUMBER() OVER (Order By DocumentID desc) peta_rn, peta_query.* From 
    (
            Select   d.DocumentID, d.IsReEfiled, d.IGroupID, d.ITypeID, d.RecordingDateTime, dbo.GetLatestStatusDateTime(d.DocumentID) as LatestStatusDatetime, 
                    dbo.FnCanChangeDocumentStatus(d.DocumentStatusID,d.DocumentID) as CanChangeStatus, 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,
                    dbo.GetFlatDocumentName(d.DocumentID) as FlatDocumentName 
                    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                           
    ) as peta_query) peta_paged WHERE peta_rn>12000 AND peta_rn<=12100

ただし、この 2 番目のクエリは 1 秒で実行されます。

SELECT * FROM (SELECT 
    peta_query.* From 
    (
            Select  ROW_NUMBER() OVER (Order By d.DocumentID desc) peta_rn, d.DocumentID, d.IsReEfiled, d.IGroupID, d.ITypeID, d.RecordingDateTime, dbo.GetLatestStatusDateTime(d.DocumentID) as LatestStatusDatetime, 
                    dbo.FnCanChangeDocumentStatus(d.DocumentStatusID,d.DocumentID) as CanChangeStatus, 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,
                    dbo.GetFlatDocumentName(d.DocumentID) as FlatDocumentName 
                    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                           
    ) as peta_query) peta_paged WHERE peta_rn>12000 AND peta_rn<=12100

私の質問は次のとおりです。

1)最初のクエリの実行に時間がかかる理由を教えてください。自動化されたプログラムの1つによって生成されるため、最初のクエリを最適化したいと思います(そのソースはありますが、Select内でRowNumberを移動できません)。

2)これを実行する時間は、peta_rn にも依存します。peta_rn > 50000 および peta_rn <= 50100 を指定すると、実行に絶望的な時間がかかります。また、最終的には一度に 100 行しかフェッチしようとしないため、フェッチしようとしている行によって実行時間が異なる理由を教えてください。

4

1 に答える 1

1

楽しみのために、この CTE を試して、どのように機能するかを確認できますか?? そこに 3 つのネストされたサブクエリがある理由が完全にはわかりません....

;WITH PetaQuery AS
(
    SELECT 
        ROW_NUMBER() OVER (ORDER BY d.DocumentID DESC) peta_rn, 
        d.DocumentID, d.IsReEfiled, d.IGroupID, d.ITypeID, d.RecordingDateTime, 
        dbo.GetLatestStatusDateTime(d.DocumentID) as LatestStatusDatetime, 
        dbo.FnCanChangeDocumentStatus(d.DocumentStatusID,d.DocumentID) as CanChangeStatus, 
        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,
        dbo.GetFlatDocumentName(d.DocumentID) as FlatDocumentName 
    FROM 
        Documents d 
    INNER JOIN 
        IGroupes ig On d.IGroupID = ig.IGroupID 
    LEFT OUTER JOIN 
        ITypes it On d.ITypeID = it.ITypeID 
    LEFT OUTER JOIN 
        Users u On u.UserID = d.UserID 
    LEFT OUTER JOIN 
        DocumentStatuses ds On d.DocumentStatusID = ds.DocumentStatusID 
    LEFT OUTER JOIN 
        InstrumentFiles inf On d.DocumentID = inf.DocumentID 
    INNER JOIN 
        Jurisdictions j on j.JurisdictionID = d.JurisdictionID                           
) 
SELECT * FROM PetaQuery
WHERE peta_rn > 12000 AND peta_rn <= 12100

これは元のクエリと同じ応答時間ですか?

その場合は、次を確認してください。

  • すべての外部キー ( IGroupIDITypeIDUserIDDocumentStatusID、 )DocumentIDにインデックスがありますJurisdictionIDか? これは、高速な JOIN パフォーマンスにとって重要です
于 2012-10-17T05:09:54.470 に答える