Оптимизация SQL-запроса, который выполняется медленно с большими данными - PullRequest
0 голосов
/ 01 февраля 2019

Я использую Microsoft SQL Server 2012. Я создал один запрос, чтобы получить подробную информацию, но он работает медленно с большими данными.Вот запрос:

SELECT p.BackgroundID,
       sum(od.OrderQuantity) AS number
FROM approval.orderdetail od(nolock)
JOIN project p(nolock) ON od.ProjectID = p.projectid
AND p.BackgroundID IS NOT NULL
WHERE CAST(p.ModifiedDateUTC AS DATE) BETWEEN @startDate AND @endDate
  AND EXISTS
    (SELECT backgroundid
     FROM background b
     WHERE b.BackgroundID = p.BackgroundID
       AND (@isActive = 2
            OR b.IsActive = @isActive)
       AND (@filtertype = 0
            OR ((@filtertype IN (3, 5, 7, 8)
                 AND b.licenseid IS NULL
                 AND b.IsAR = 0)
                OR (@filtertype IN (1, 4, 5)
                    AND b.IsAR = 1)
                OR (@filtertype IN (2, 4, 6)
                    AND b.IsLicensed = 1))))
GROUP BY p.BackgroundID

Может кто-нибудь помочь мне оптимизировать запрос?Любые предложения по оптимизации производительности.

В настоящее время, когда я запускаю этот запрос в первый раз с большими данными, он обрабатывает почти 1 минуту, а затем при повторном запуске он обрабатывает только 3 секунды.

Вот план выполнения: План выполнения

Ответы [ 2 ]

0 голосов
/ 01 февраля 2019

Попробуйте это:

SELECT p.BackgroundID,
       sum(od.OrderQuantity) AS number
FROM approval.orderdetail od(nolock)
JOIN project p(nolock) ON od.ProjectID = p.projectid AND p.BackgroundID IS NOT NULL
JOIN background b ON b.BackgroundID = p.BackgroundID
WHERE 
  (@isActive = 2
            OR b.IsActive = @isActive)
       AND (@filtertype = 0
            OR ((@filtertype IN (3, 5, 7, 8)
                 AND b.licenseid IS NULL
                 AND b.IsAR = 0)
                OR (@filtertype IN (1, 4, 5)
                    AND b.IsAR = 1)
                OR (@filtertype IN (2, 4, 6)
                    AND b.IsLicensed = 1))))
  AND
  CAST(p.ModifiedDateUTC AS DATE) BETWEEN @startDate AND @endDate
GROUP BY p.BackgroundID

Попробуйте воспроизвести предложение Exists с помощью inner join и переставить фильтры, которые в первую очередь рассматривают фильтр, в котором есть индексы.

0 голосов
/ 01 февраля 2019

Он запускается быстрее во второй раз, когда вы его выполняете, потому что движок может повторно использовать план для этого запроса, который был создан при первом запуске.Так что теперь так и должно быть.Если вы все еще не удовлетворены, пожалуйста, включите план выполнения в свой вопрос.Я бы предложил удалить CAST из ModifiedDateUTC - результат должен быть таким же, но он не позволяет использовать индекс для этого поля, если он существует.

...