Оптимизация запросов SQL Server - PullRequest
1 голос
/ 22 сентября 2011

Я унаследовал этот адский запрос, разработанный для разбивки на страницы в 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 

1 Ответ

0 голосов
/ 22 сентября 2011

Я нахожусь в той же позиции, что и запросы того же рода. Вот несколько советов:

  • Посмотрите на планы запросов, чтобы убедиться, что у вас есть правильные индексы.
  • Я не уверен, оптимизирует ли 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 

, что должно заставить оптимизатор запросов вести себя немного лучше.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...