2011-09-22 192 views
1

我繼承了這個在SQL Server中爲分頁設計的地獄般的查詢。SQL Server查詢優化

它只能獲得25條記錄,但根據SQL Profiler,它可以讀取8091條記錄,寫入208條記錄,耗時74毫秒。寧願它快一點。 ORDER BY列deployDate上有一個索引。

任何人有任何想法如何優化它?

SELECT TOP 25 
    textObjectPK, textObjectID, title, articleCredit, mediaCredit, 
    commentingAllowed,deployDate, 
    container, mediaID, mediaAlign, fileName AS fileName, fileName_wide AS fileName_wide, 
    width AS width, height AS height,title AS mediaTitle, extension AS extension, 
    embedCode AS embedCode, jsArgs as jsArgs, description as description, commentThreadID, 
    totalRows = Count(*) OVER() 
FROM 
    (SELECT 
     ROW_NUMBER() OVER (ORDER BY textObjects.deployDate DESC) AS RowNumber, 
     textObjects.textObjectPK, textObjects.textObjectID, textObjects.title, 
     textObjects.commentingAllowed, textObjects.credit AS articleCredit, 
     textObjects.deployDate, 
     containers.container, containers.mediaID, containers.mediaAlign, 
     media.fileName AS fileName, media.fileName_wide AS fileName_wide, 
     media.width AS width, media.height AS height, media.credit AS mediaCredit, 
     media.title AS mediaTitle, media.extension AS extension, 
     mediaTypes.embedCode AS embedCode, media.jsArgs as jsArgs, 
     media.description as description, commentThreadID, 
     TotalRows = COUNT(*) OVER() 
    FROM textObjects WITH (NOLOCK) 
    INNER JOIN containers WITH (NOLOCK) 
       ON containers.textObjectPK = textObjects.textObjectPK 
       AND (containers.containerOrder = 0 or containers.containerOrder = 1) 
    INNER JOIN LUTextObjectTextObjectGroup tog WITH (NOLOCK) 
       ON textObjects.textObjectPK = tog.textObjectPK 
       AND tog.textObjectGroupID in (3) 
    LEFT OUTER JOIN media WITH (NOLOCK) 
       ON containers.mediaID = media.mediaID 
    LEFT OUTER JOIN mediaTypes WITH (NOLOCK) 
       ON media.mediaTypeID = mediaTypes.mediaTypeID 
    WHERE (((version = 1) 
       AND (textObjects.textObjectTypeID in (6)) 
     AND (DATEDIFF(minute, deployDate, GETDATE()) >= 0) 
     AND (DATEDIFF(minute, expireDate, GETDATE()) <= 0)) 
     OR ((version = 1) AND (textObjects.textObjectTypeID in (6)) 
     AND (DATEDIFF(minute, deployDate, GETDATE()) >= 0) 
     AND (expireDate IS NULL))) 
     AND deployEnglish = 1 
     ) tmpInlineView 
    WHERE RowNumber >= 51 
    ORDER BY deployDate DESC 
+0

執行計劃? –

+1

你有沒有以前的開發者的地址,所以你可以用管道炸死他?也就是說,74ms對所有這些並不壞,特別是考慮到我的理解是MSSQL由於缺少像MySQL那樣的「LIMIT 」而對分頁有點痛苦。 – ceejayoz

+2

那混亂在74毫秒運行? –

回答

0

我處於與相同類型的查詢類似的位置。這裏有一些提示:

  • 看看查詢計劃,以確保您有正確的索引。
  • 我不確定MSSQL是否優化了DATEDIFF(),但是如果不是,您可以預先計算閾值日期並將其轉換爲BETWEEN子句。
  • 如果您不需要按照您的ROW_NUMBER()子句中的所有列進行排序,請刪除它們。這可能允許您在更簡單的查詢上執行分頁,然後只需獲取您要返回的25行所需的額外數據。

而且,改寫兩個LEFT OUTER JOINs這樣的:

LEFT OUTER JOIN 
(
    media WITH (NOLOCK) 
     LEFT OUTER JOIN mediaTypes WITH (NOLOCK) 
      ON media.mediaTypeID = mediaTypes.mediaTypeID 
) 
    ON containers.mediaID = media.mediaID 

這將使查詢優化器表現更好一點。