Sql View с предложением WHERE работает медленнее, чем необработанный запрос

Это выполняется за постоянное время:

 SELECT row_number() OVER (order by PackagingUniqueId) as RowNum, Barcode, pu.PackagingUniqueId,
rd.Name, pu.ComponentBarcode, rrl.ponum, rrl.mfgpart, rrl.new_lot_code, rrl.pno
    FROM Trace.dbo.TraceData td
    INNER JOIN Trace.dbo.TraceJob tj ON td.Id = tj.TraceDataId
    INNER JOIN Trace.dbo.Job j ON tj.JobId = j.Id
    INNER JOIN Trace.dbo.[Order] o ON j.OrderId = o.id
    INNER JOIN Trace.dbo.PCBBarcode p ON td.PCBBarcodeId = p.Id
    INNER JOIN Trace.dbo.TracePlacement tp ON td.Id = tp.TraceDataId
    INNER JOIN Trace.dbo.Placement p2 ON p2.PlacementGroupId = tp.PlacementGroupId
    INNER JOIN Trace.dbo.Charge c ON p2.ChargeId = c.Id
    INNER JOIN Trace.dbo.PackagingUnit pu ON c.PackagingUnitId = pu.Id
    INNER JOIN Trace.dbo.RefDesignator rd ON p2.RefDesignatorId = rd.Id
    INNER JOIN SpotlightSQL.spot_light_dbo.peel_off_ids po ON po.peel_off_id = pu.PackagingUniqueId
    INNER JOIN SpotlightSQL.spot_light_dbo.recv_receipts_log rrl ON rrl.label_id = po.label_id
    WHERE p.Barcode = '20092619153'

Однако это занимает около 7 секунд:

SELECT * FROM Component WHERE Barcode = '20092619153'

Компонент - это представление SQL, которое состоит из первого более длинного запроса без предложения WHERE.

Почему так происходит? Получает ли представление все записи, а затем применяет предложение Where? Есть ли способ ускорить выполнение второго запроса? (без применения индексов)


person Ilkin Sam Elimov    schedule 23.04.2020    source источник
comment
sqlperformance.com/2013/ 03 / t-sql-query /   -  person Mitch Wheat    schedule 23.04.2020
comment
@MitchWheat Должен спросить, что случилось с изображением головы лошади? Это серьезно напоминает мне это музыкальное видео Neon Trees.   -  person Tim Biegeleisen    schedule 23.04.2020


Ответы (1)


Почему так происходит? Получает ли представление все записи, а затем применяет предложение Where?

Да, в этом конкретном случае SQL Server сначала выполнит исходный базовый запрос, а затем применит фильтр WHERE поверх этого промежуточного результата.

Есть ли способ ускорить выполнение второго запроса? (без применения индексов)

Представление SQL обычно работает так же хорошо, как и базовый запрос. Итак, если Barcode - хороший способ отфильтровать множество записей, то добавление индекса к Barcode - лучший способ. Кроме этого, вы мало что можете сделать, чтобы ускорить просмотр.

Один из вариантов - создать материализованное представление, которое по сути представляет собой просто таблицу, данные которой генерируются запросом вашего представления. Выбор всех записей из материализованного представления без дополнительных ограничений должен иметь скорость, ограниченную только временем передачи данных.

person Tim Biegeleisen    schedule 23.04.2020
comment
SQL Server сначала выполнит исходный базовый запрос - я уверен, что это не так, если нет чего-то, что препятствует передаче параметров (например, агрегации). В этом случае это вызовет row_number (). - person Mitch Wheat; 23.04.2020
comment
Тогда почему представление не имеет идентичной производительности базовому запросу? - person Tim Biegeleisen; 23.04.2020
comment
dba.stackexchange.com/questions/172208/ - person Mitch Wheat; 23.04.2020
comment
@MitchWheat Спасибо за комментарий, не знал, что СУБД оптимизирует представление таким образом. - person Tim Biegeleisen; 23.04.2020
comment
также: sqlperformance.com/ 03.03.2013 / t-sql-query / - person Mitch Wheat; 23.04.2020
comment
Ух ты! Спасибо вам, ребята. Я пробовал без row_number () и просмотр запускается в постоянное время! - person Ilkin Sam Elimov; 23.04.2020