简体   繁体   English

SQL Server查询优化

[英]SQL Server query optimisation

I inherited this hellish query designed for pagination in SQL Server. 我继承了这个专为SQL Server分页设计的地狱查询。

It's only getting 25 records, but according to SQL Profiler, it does 8091 reads, 208 writes and takes 74 milliseconds. 它仅获得25条记录,但是根据SQL Profiler的数据,它执行8091次读取,208次写入并花费74毫秒。 Would prefer it to be a bit faster. 希望它快一点。 There is an index on the ORDER BY column deployDate . ORDER BY列deployDate上有一个索引。

Anyone have any ideas on how to optimise it? 有人对如何优化它有任何想法吗?

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 

I am in a similar position to with the same sort of queries. 我处于与相同查询相似的位置。 Here are some tips: 这里有一些提示:

  • Look at the query plans to make sure you have the right indexes. 查看查询计划以确保您具有正确的索引。
  • I'm not sure if MSSQL optimizes around DATEDIFF(), but if it doesn't you can precompute threshold dates and turn it into a BETWEEN clause. 我不确定MSSQL是否围绕DATEDIFF()进行优化,但是如果不是,则可以预先计算阈值日期并将其转换为BETWEEN子句。
  • If you don't need to order by all those columns in your ROW_NUMBER() clause, get rid of them. 如果您不需要按ROW_NUMBER()子句中的所有这些列进行排序,请除去它们。 That may allow you to do the pagination on a much simpler query, then just grab the extra data you need for the 25 rows you are returning. 这可能使您可以对一个简单得多的查询进行分页,然后仅获取要返回的25行所需的额外数据。

Also, rewrite the two LEFT OUTER JOINs like this: 另外,像这样重写两个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 

which should make the query optimizer behave a little better. 这应该使查询优化器的性能更好一些。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM