2012-10-17 169 views
1

我在DB各地90K的記錄,我運行此查詢:查詢與ROW_NUMBER()花費過多時間

它需要太多的時間(約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 

然而,這第二查詢執行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)你能否建議爲什麼我的第一個查詢需要這麼長時間來執行?我想優化我的第一個查詢,因爲它是由一個自動化程序生成的(它的源代碼有,但我不能移動Select中的RowNumber)。

2)執行此操作的時間也取決於peta_rn。如果我給peta_rn> 50000和peta_rn < = 50100,則需要執行無望的時間。你能否也請建議爲什麼要執行的時間取決於我試圖讀取的行,因爲最終我只試圖一次讀取100行。

+0

你有沒有索引peta_rn?它會提高你的查詢性能。 – Habibillah

+0

@habibillah:我應該如何索引peta_rn?它只是一個計算字段,它是* ROW_NUMBER()OVER(按d.DocumentID desc排序)* – Jack

回答

1

只是爲了它的樂趣 - 你可以試試這個CTE,看看它是如何執行的?我不完全理解爲什麼你有三個嵌套子查詢有....

;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 

這是否具有相同的響應時間爲原始查詢?

如果是這樣,請檢查:

  • 你有你的所有外鍵索引(IGroupIDITypeIDUserIDDocumentStatusIDDocumentIDJurisdictionID)?這對快速加入性能至關重要
+0

這個需要2秒鐘(在我修復了一些錯誤,如使用PetaQuery而不是peta_query並使用d.DocumentID代替DocumentID。 ,我沒有外鍵索引,請允許我這樣做,謝謝你的提示 – Jack

+0

你能否建議爲什麼執行時間取決於peta_rn?如果我的peta_rn> 52000和peta_rn <= 52100在你的查詢中需要4秒,是否row_number本身效率低下? – Jack

+0

@Jack:檢查兩個執行計劃!他們傾向於告訴你很多關於事情如何工作以及發生了什麼......我不認爲它是'row_number()'這是責怪 - 更可能是你的許多''左外部連接'..... –