В нашей базе данных 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) при выполнении параметризированных запросов, который обычно имеет смысл (кэширование плана запросов, и т.д.). В нашем случае, однако, это уничтожает производительность. Так, есть ли некоторый путь к также
sp_executesql
(т.е. что-то, где запрос SQL Server анализатор принимает фактические значения параметров во внимание), ИЛИsp_executesql
принятие во внимание значений параметров?И не говорите мне, что я должен вернуться к ужасному, старому, опасному sql = "WHERE b = " + quoteAndEscape(parameterB)
...
Помещение SQL в хранимую процедуру не имеет никакого значения (медленный, с и без WITH RECOMPILE
). Я не отправил фактический SQL statment, так как это довольно сложно (соединения по нескольким таблицам, включая ПОДВЫБОРЫ и агрегирование).
Вы Может ли попробовать оптимизировать для подсказки запроса , который (цитата):
поручает оптимизатору запросов использовать конкретное значение для локальной переменной Когда запрос скомпилирован и оптимизирован. Значение используется только во время оптимизации запроса, а не во время выполнения запроса. Оптимизировать за может противодействовать обнаружению параметра поведение оптимизатора или может быть Используется, когда вы создаете направляющие плана