Я хотел бы спросить ваше мнение, когда дело доходит до реализации фильтрованной формы поиска. Давайте представим следующий случай:
- 1 большой стол с множеством колонн
- Может быть важно сказать, что этот SQL Server
Вам нужно реализовать форму для поиска данных в этой таблице, и в этой форме у вас будет несколько флажков, которые позволят вам оценить этот поиск.
Теперь у меня вопрос: какой из следующих способов должен быть наилучшим для осуществления поиска?
Создайте хранимую процедуру с запросом внутри. Эта хранимая процедура проверит, если параметры заданы приложением, а в случае, если они не заданы, в запрос будет вставлен подстановочный знак.
Создайте динамический запрос, построенный в соответствии с тем, что дано приложением.
Я спрашиваю об этом, потому что знаю, что SQL Server создает план выполнения при создании хранимой процедуры, чтобы оптимизировать ее производительность, однако, создав динамический запрос внутри хранимой процедуры, пожертвуем ли мы оптимизацией, полученной планом выполнения?
Пожалуйста, скажите мне, что было бы лучшим подходом в вашем мнении.
Ответы:
Возможно, вы захотите посмотреть ответ на этот похожий вопрос здесь: /programming/11329823/add-where-clauses-to-sql-dynamically-programmatics
Мы обнаружили, что SPROC принимает множество необязательных параметров и реализует фильтр следующим образом:
будет кешировать первый план выполнения, с которым он запускается (например
@optionalParam1 = 'Hello World', @optionalParam2 = NULL
), но затем выполнится с треском, если мы передадим ему другой набор необязательных параметров (например@optionalParam1 = NULL, @optionalParam2 = 42
). (И, очевидно, мы хотим, чтобы производительность кэшированного плана, такWITH RECOMPILE
что нет)Исключением здесь является то, что если в запросе также есть хотя бы один ОБЯЗАТЕЛЬНЫЙ фильтр, который ВЫСОКО селективен и правильно проиндексирован, в дополнение к необязательным параметрам, то вышеупомянутый PROC будет работать нормально.
Однако, если ВСЕ фильтры являются необязательными, довольно ужасная истина заключается в том, что параметризованный динамический sql действительно работает лучше (если вы не напишите N! Различных статических PROCS для каждой перестановки необязательных параметров).
Динамический SQL, подобный приведенному ниже, будет создавать и кэшировать отдельный план для каждой перестановки параметров запроса, но по крайней мере каждый план будет «адаптирован» для конкретного запроса (не имеет значения, является ли он PROC или Adhoc SQL - как Пока они являются параметризованными запросами, они будут кэшироваться)
Поэтому отсюда мое предпочтение:
и т.д. Неважно, если мы передадим избыточные параметры в sp_executesql - они игнорируются. Стоит отметить, что ORM, такие как Linq2SQL и EF, используют параметризованный динамический sql аналогичным образом.
источник
Начните с того, что, по вашему мнению, проще реализовать (я думаю, вариант 2). Затем измерьте производительность для реальных данных. Оптимизацию можно начинать только тогда, когда это необходимо, а не заранее.
Кстати, в зависимости от того, насколько сложны ваши поисковые фильтры, ваша задача не может быть легко решена без динамического SQL. Таким образом, даже если вы используете хранимую процедуру, это, скорее всего, не увеличит производительность, как вы уже подозревали. С другой стороны, если это помогает, есть несколько типов подсказок (см. Http://www.simple-talk.com/sql/performance/controlling-execution-plans-with-hints/ ), которые можно добавить в SQL запрос, динамический или нет, чтобы помочь SQL-серверу оптимизировать свой план выполнения.
источник