Я не понимаю, почему этот запрос выполняется медленно

#sql #sql-server #query-performance

#sql #sql-server #производительность запросов

Вопрос:

У меня есть медленный запрос к нашей базе данных Microsoft sql. И если я удаляю его часть, это ускоряется, но я не понимаю почему, и планировщик запросов мне не помогает (я чего-то не понимаю).

Запрос, который выполняется медленно > 30 секунд (queryplan):

 SELECT COUNT(*)
FROM [dbo].[CarImage] AS [t0]
     LEFT OUTER JOIN [dbo].[Dismantled] AS [t1] ON [t1].[Id] = [t0].[DismantledId]
WHERE([t1].[FinishedReason] <> 0)
     AND ([t1].[FinishedDate] < GETDATE() - 365)
     AND (NOT(EXISTS
(
    SELECT NULL AS [EMPTY]
    FROM [dbo].[Part] AS [t2]
    WHERE([t2].[Status] <> 4)
         AND ([t2].[Status] <> 3)
         AND ([t2].[DismantledId] = [t1].[Id])
)))
     AND (NOT(EXISTS
(
    SELECT NULL AS [EMPTY]
    FROM [dbo].[Part] AS [t3]
    WHERE([t3].[Status] = 3)
         AND ([t3].[SoldDate] > GETDATE() - 365)
         AND ([t3].[DismantledId] = [t1].[Id])
)))
     AND ((NOT(EXISTS
(
    SELECT NULL AS [EMPTY]
    FROM [dbo].[Partner] AS [t4], 
         [dbo].[SelfPickSite] AS [t5]
    WHERE([t4].[Id] = [t1].[PartnerId])
         AND ([t5].[PartnerId] = [t4].[Id])
)))
          OR (EXISTS
(
    SELECT NULL AS [EMPTY]
    FROM [dbo].[SelfPickCar] AS [t6]
    WHERE [t6].[DismantledId] = [t1].[Id]
)));
 

Если я удалю последнюю часть, это <1 сек (queryplan):

 SELECT COUNT(*)
FROM [dbo].[CarImage] AS [t0]
     LEFT OUTER JOIN [dbo].[Dismantled] AS [t1] ON [t1].[Id] = [t0].[DismantledId]
WHERE([t1].[FinishedReason] <> 0)
     AND ([t1].[FinishedDate] < GETDATE() - 365)
     AND (NOT(EXISTS
(
    SELECT NULL AS [EMPTY]
    FROM [dbo].[Part] AS [t2]
    WHERE([t2].[Status] <> 4)
         AND ([t2].[Status] <> 3)
         AND ([t2].[DismantledId] = [t1].[Id])
)))
     AND (NOT(EXISTS
(
    SELECT NULL AS [EMPTY]
    FROM [dbo].[Part] AS [t3]
    WHERE([t3].[Status] = 3)
         AND ([t3].[SoldDate] > GETDATE() - 365)
         AND ([t3].[DismantledId] = [t1].[Id])
)))
     AND ((NOT(EXISTS
(
    SELECT NULL AS [EMPTY]
    FROM [dbo].[Partner] AS [t4], 
         [dbo].[SelfPickSite] AS [t5]
    WHERE([t4].[Id] = [t1].[PartnerId])
         AND ([t5].[PartnerId] = [t4].[Id])
))));
 

Комментарии:

1. Не могли бы вы дать некоторые подробности о запросе и части, которую вы удалили? Без какого-либо контекста помочь вам будет невозможно

2. Извините, я случайно опубликовал перед добавлением всего содержимого. Теперь он обновлен.

Ответ №1:

ИЛИ убивает производительность; пожалуйста, попробуйте этот запрос и дайте мне результат

   SELECT COUNT(*)
    FROM (
        SELECT 1
        FROM [dbo].[CarImage] AS [t0]
        LEFT JOIN [dbo].[Dismantled] AS [t1] ON [t1].[Id] = [t0].[DismantledId]
        WHERE ([t1].[FinishedReason] <> 0)
            AND ([t1].[FinishedDate] < GETDATE() - 365)
            AND (
                NOT (
                    EXISTS (
                        SELECT NULL AS [EMPTY]
                        FROM [dbo].[Part] AS [t2]
                        WHERE ([t2].[Status] <> 4)
                            AND ([t2].[Status] <> 3)
                            AND ([t2].[DismantledId] = [t1].[Id])
                        )
                    )
                )
            AND (
                NOT (
                    EXISTS (
                        SELECT NULL AS [EMPTY]
                        FROM [dbo].[Part] AS [t3]
                        WHERE ([t3].[Status] = 3)
                            AND ([t3].[SoldDate] > GETDATE() - 365)
                            AND ([t3].[DismantledId] = [t1].[Id])
                        )
                    )
                )
            AND (
                (
                    NOT (
                        EXISTS (
                            SELECT NULL AS [EMPTY]
                            FROM [dbo].[Partner] AS [t4]
                                ,[dbo].[SelfPickSite] AS [t5]
                            WHERE ([t4].[Id] = [t1].[PartnerId])
                                AND ([t5].[PartnerId] = [t4].[Id])
                            )
                        )
                    )

                UNION ALL

                SELECT 1
                FROM [dbo].[CarImage] AS [t0]
                LEFT JOIN [dbo].[Dismantled] AS [t1] ON [t1].[Id] = [t0].[DismantledId]
                WHERE (
                        EXISTS (
                            SELECT NULL AS [EMPTY]
                            FROM [dbo].[SelfPickCar] AS [t6]
                            WHERE [t6].[DismantledId] = [t1].[Id]
                            )
                        )
                )
        ) X
 

ps: если у вас проблемы с производительностью, запустите этот код SET STATISTICS IO ON , а затем запустите запрос и опубликуйте результат

Комментарии:

1. Похоже, здесь ошибка. Вы ввели Union all, union с чем? выше не существует?

2. Извините, что я разместил сообщение через мобильный телефон, вместо или используйте 2 инструкции выбора