2011-09-22 154 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 

这将使查询优化器表现更好一点。