Препятствуйте тому, чтобы ADO.NET использовал sp_executesql

В нашей базе данных SQL Server 2005 (протестированный Studio управления использованием с DBCC FREEPROCCACHE и DBCC DROPCLEANBUFFERS), следующее утверждение быстро (~0.2s время компиляции, ~0.1s время выполнения):

SELECT ... FROM ... WHERE a = 1 AND b = '' ...

Следующее утверждение, однако, является медленным (~0.2s время компиляции, 7-11s время выполнения):

exec sp_executesql N'SELECT ... FROM ... WHERE a = @a AND b = @b ...', N'@a int, @b nvarchar(4000), ...', @a=1, @b=N'', ...

SQL Server выбирает другой план выполнения, хотя запросы равны. Это имеет смысл, с тех пор, в первом случае, SQL Server имеет фактические значения a, b и все другие доступные параметры и могут использовать статистику для создания лучшего плана. По-видимому, план запросов для конкретных значений параметров намного лучше, чем универсальный и определенно перевешивает любой "план запросов, кэширующий" выигрыш в производительности.

Теперь мой вопрос: ADO.NET всегда, кажется, использует вторую опцию (sp_executesql) при выполнении параметризированных запросов, который обычно имеет смысл (кэширование плана запросов, и т.д.). В нашем случае, однако, это уничтожает производительность. Так, есть ли некоторый путь к также

  • вынудите ADO.NET использовать что-то другое, чем sp_executesql (т.е. что-то, где запрос SQL Server анализатор принимает фактические значения параметров во внимание), ИЛИ
  • вызовите SQL Server к recaclulate, которому передал план запросов SQL sp_executesql принятие во внимание значений параметров?

И не говорите мне, что я должен вернуться к ужасному, старому, опасному sql = "WHERE b = " + quoteAndEscape(parameterB)...

Помещение SQL в хранимую процедуру не имеет никакого значения (медленный, с и без WITH RECOMPILE). Я не отправил фактический SQL statment, так как это довольно сложно (соединения по нескольким таблицам, включая ПОДВЫБОРЫ и агрегирование).

6
задан Heinzi 14 December 2015 в 08:52
поделиться

1 ответ

Вы Может ли попробовать оптимизировать для подсказки запроса , который (цитата):

поручает оптимизатору запросов использовать конкретное значение для локальной переменной Когда запрос скомпилирован и оптимизирован. Значение используется только во время оптимизации запроса, а не во время выполнения запроса. Оптимизировать за может противодействовать обнаружению параметра поведение оптимизатора или может быть Используется, когда вы создаете направляющие плана

2
ответ дан 16 December 2019 в 21:40
поделиться
Другие вопросы по тегам:

Похожие вопросы: