У мене це питання було давно, я знайшов рішення, яке мені підходило, і забув про нього.
Але зараз це питання щодо ТА, тому я готовий вирішити цю проблему.
Існує думка, що об'єднує кілька таблиць дуже просто (накази + рядки замовлення).
При запиті без where
пропозиції перегляд повертає кілька мільйонів рядків.
Однак ніхто ніколи не називає це так. Звичайний запит є
select * from that_nasty_view where order_number = 123456;
Це повертає близько 10 записів з 5 м.
Важлива річ: представлення містить функцію вікна rank()
, яка розділяється точно на поле, за допомогою якого погляд завжди запитується:
rank() over (partition by order_number order by detail_line_number)
Тепер, якщо цей погляд запитується з буквальними параметрами в рядку запиту, точно так, як показано вище, він повертає рядки миттєво. План виконання:
- Шукайте індекси в обох таблицях, використовуючи індекси на
order_number
(повертає 10 рядків). - Обчислення вікон за поверненим крихітним результатом.
- Вибір.
Однак, коли вигляд викликається параметризованим чином, справи стають неприємними:
Index scan
на всіх таблицях ігнорування індексів. Повертається 5м рядків.- Величезне приєднання.
- Обчислення вікон для всіх
partition
s (близько 500k вікон). Filter
взяти 10 рядів з 5м.- Виберіть
Це відбувається у всіх випадках, коли задіяні параметри. Це можуть бути SSMS:
declare @order_number int = 123456;
select * from that_nasty_view where order_number = @order_number;
Це може бути клієнт ODBC, такий як Excel:
select * from that_nasty_view where order_number = ?
Або це може бути будь-який інший клієнт, який використовує параметри, а не з’єднання sql.
Якщо віконну функцію видалити з подання, вона працює ідеально швидко, незалежно від того, запитується вона за параметрами.
Моє вирішення полягало в тому, щоб видалити функцію, що порушує право, та застосувати її на подальшому етапі.
Але, що дає? Це справді помилка в тому, як SQL Server 2008 обробляє віконні функції?
order_number
не є первинним ключем. Він int not null
з некластеризованим індексом на ньому в обох таблицях.
OPTION (RECOMPILE)
допомога?