У мене є наступний запит:
select databasename
from somedb.dbo.bigtable l where databasename ='someval' and source <>'kt'
and not exists(select 1 from dbo.smalltable c where c.source=l.source)
Наведений вище запит виконується за три секунди.
Якщо вищезазначений запит повертає будь-яке значення, ми хочемо, щоб збережена процедура EXIT, тому я переписав її як нижче:
If Exists(
select databasename
from somedb.dbo.bigtable l where databasename ='someval' and source <>'kt'
and not exists(select 1 from dbo.smalltable c where c.source=l.source)
)
Begin
Raiserror('Source missing',16,1)
Return
End
Однак це займає 10 хвилин.
Я можу переписати вищезазначений запит, як нижче, який також виконується менше ніж за 3 секунди:
select databasename
from somedb.dbo.bigtable l where databasename ='someval' and source <>'kt'
and not exists(select 1 from dbo.smalltable c where c.source=l.source
if @@rowcount >0
Begin
Raiserror('Source missing',16,1)
Return
End
Проблема з перезаписом вище полягає в тому, що вищезазначений запит є частиною більшої збереженої процедури і він повертає кілька наборів результатів. У C # ми повторюємо кожен набір результатів і робимо деяку обробку.
Вищезазначене повертає порожній набір результатів, тому якщо я переходжу з таким підходом, мені доведеться змінити свій C # і знову розгорнути.
Отже, моє питання:
чому використання просто
IF EXISTS
зміни плану займає стільки часу?
Нижче наведено деталі, які можуть вам допомогти, і повідомте мене, якщо вам потрібні якісь деталі:
- Створіть таблицю та сценарій статистики, щоб отримати той же план, що і мій
- План повільного виконання
План швидкого виконання
Повільний план за допомогою Brentozar Вставте план
швидкого плану за допомогою Brentozar Paste
Примітка. Обидва запити однакові (з використанням параметрів), різниця полягає лише в тому, що EXISTS
(можливо, я помилився, хоч анонімізував).
Сценарії створення таблиці наведені нижче:
http://pastebin.com/CgSHeqXc - маленька статистика таблиці
http://pastebin.com/GUu9KfpS - велика статистика таблиці