Коли sp_executesql оновлює план запитів?


13

Вам доведеться пробачити мою наївність, оскільки я не DBA, але я розумію, що з часом статистика зміни бази даних і збережена процедура повинні бути перекомпільовані, щоб тримати план запитів в курсі останніх статистичних даних.

Якщо припустити, що у моїй базі даних є збережена процедура, яка перекомпільована проти останніх статистичних даних на певному регулярному інтервалі, які наслідки є вбудовування збереженої процедури в код та загортання її у sp_executesqlвиписку? Чи втрачаю я оновлення плану запитів, який раніше відбувався в рамках перекомпіляції процедури?

Якщо є щось інше (окрім дозволів), що мені потрібно розглянути, перш ніж вносити цю зміну, то я буду вдячний за вашу думку.

Я читав це на MSDN:

Можливість оптимізатора запитів SQL Server співставляти нову рядок Transact-SQL з існуючим планом виконання заважає постійно змінюються значенням параметрів у тексті рядка, особливо у складних операторах Transact-SQL.

Отже, якщо припустити, що збережена процедура, яку я намагаюся встроїти і завершити sp_executesql, дійсно містить деякі параметри, чи це говорить про те, що, хоча мій план виконання є кешованим, я ускладнюю його пошук і повторне використання SQL Server?

Відповіді:


7

У рядку від MSDN йдеться про використання EXEC(), наприклад:

SET @sql = 'SELECT foo FROM dbo.bar WHERE x = ''' + @x + ''';';
EXEC(@sql);

У моєму тестуванні сучасні версії SQL Server все ще можуть використовувати повторно подібний план, але можуть бути й інші змінні (наприклад, версія або, наприклад, якщо ви додаєте умовні WHEREпропозиції на основі наявності певних параметрів - у цьому випадку створить інший план).

Якщо ви використовуєте, sp_executesqlтоді значення параметрів все ще можуть спричинити проблеми з нюхом параметрів (як і у звичайному SQL), але це не має нічого спільного з тим, чи може SQL Server повторно використовувати план. Цей план буде використовуватися знову і знову так само, як ніби ви його взагалі не використовували sp_executesql, за винятком випадків, коли змінні, які спричинили б перекомпіляцію прямого запиту, і в цьому випадку цей також буде перекомпільований (по суті, SQL Server не зберігати що-небудь з планом, який говорить "це було виконано з sp_executesql, але цього не було):

SET @sql = N'SELECT foo FROM dbo.bar WHERE x = @x;';
EXEC sp_executesql @sql, N'@x VARCHAR(32)', @x;

Як бонус, це вбудований захист від динамічного SQL і дозволяє уникнути турботи про подвоєння одиничних лапок через обмежувачі рядків. Я щось про це блогував тут .

Якщо у вас виникли проблеми з повторним використанням та / або нюхом параметрів, деякі речі, на які слід звернути увагу OPTION (RECOMPILE), OPTIMIZE FOR- це optimize for ad hoc workloadsі simple/forced parameterization. Я звернувся до кількох подібних питань у відповідь на нещодавню веб-трансляцію тут, можливо, варто знехтувати:

http://sqlperformance.com/performance-palooza

Суть полягає в тому, що не бійтеся користуватися sp_executesql, а використовуйте лише тоді, коли вам це потрібно, і витрачайте енергію надмірно оптимізуючи її, коли у вас є проблеми з ефективністю. Наведений вище приклад - жахливий, тому що тут немає причин використовувати тут динамічний SQL - я написав цю відповідь, припускаючи, що у вас є законний випадок використання.


2

Запити, які виконуються через sp_executesql, відповідають тим же правилам планів виконання, що і звичайні запити, які не виконуються через sp_executesql. Якщо текст запиту змінюється, створюється новий план. Якщо текст не змінюється через користувача параметрів, тоді план повторно використовується. Коли статистику оновлюють, тоді плани закінчуються, а нові плани формуються при наступному запуску запиту.


Дякую за вашу відповідь, я змінив параметри, тому що тепер зрозумів, що кожного разу, коли я викликаю sp_ExecuteSql, я буду використовувати інший рядок як запит через те, що з точки зору сервера Sql я замінив параметри з жорстко кодованими значеннями (вони будуть введені в код до того, як я надішлю запит на сервер Sql). Ви знаєте спосіб цього? Чи допоможе оголошення змінних у моєму рядковому операторі sql оптимізатору запитів знайти мій план запиту кешованих даних?
james lewis
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.