Неоптимальный план выполнения с использованием sp_executesql

У меня возникают проблемы с медленной производительностью в выражении sql select с некоторыми параметрами для одного и того же запроса, выполняя этот выбор с помощью sp_executesql, так как это занимает в два раза больше времени.

Проблема заключается в том, что в sp_execute-way сервер sql не использует оптимальный план выполнения. Хотя планы разные, кажется, что в обоих случаях индексы таблиц используются правильно. Я действительно не понимаю, почему производительность настолько различна.

Мой первоначальный запрос более сложный, но чтобы попытаться выяснить, что происходит, я упростил исходный запрос к выбору с 3 таблицами и 2 соединениями. Основное различие заключается в использовании Hash Match в оптимальном режиме, я действительно не знаю смысла этого, но это единственное различие, которое я вижу.

Оптимальный план (хеш-матч, более 3 секунд)

enter image description here

Неправильный план (без хэш-совпадений, те же индексы, что и выше, более 12 секунд)

enter image description here

  • Я думаю, что моя проблема заключается не в "обнюхивании параметров", в моем случае запрос всегда медленный для всех различных значений параметров, поскольку план выполнения всегда неверен.

  • OPTION (RECOMPILE) не помогает, sp_executesql продолжает медленно, а встроенный путь занимает больше времени (потому что запрос всегда компилирует план выполнения)

  • Обновлена ​​статистика для таблиц

  • Мне нужно использовать способ sp_executesql, потому что кажется, что службы отчетов инкапсулируют выбор в sp_executesql вызовах

Кто-нибудь знает, почему sp_executesql генерирует другой (неправильный) план выполнения, чем встроенный запрос?


EDIT: запросы не использовали одни и те же индексы. Я предполагаю, что из-за того, что дерево выполнения не одно и то же, и sqlserver принимает индексы по своему усмотрению, вы можете найти новые планы выполнения, чтобы заставить использовать одни и те же индексы, производительность теперь даже хуже, от 12 секунд до более чем 15 минут (я отменил) в медленном запросе. Я действительно не заинтересован в том, чтобы запустить этот конкретный запрос с большей скоростью, поскольку я говорю, что это не тот реальный запрос, с которым я имею дело, что я пытаюсь выяснить, почему планы выполнения настолько различны между inline-query и sp_executesql -query.

Есть ли какой-либо волшебный вариант в sp_executesql, который работает правильно?:)

Optimal enter image description here

Медленная enter image description here

Ответ 1

Я понимаю, что sp_executesql сохраняет кешированный план после первого выполнения. Последующие запросы могут быть использованы в плохом кэшированном плане. Вы можете использовать следующую команду, чтобы очистить кэш процедур ENTIRE SQL Server.

    DBCC FREEPROCCACHE

http://msdn.microsoft.com/en-us/library/ms174283.aspx