Альтернатива выполнению динамического sql - PullRequest
0 голосов
/ 18 июня 2009

В настоящее время у меня есть объект «Фильтр», который соответствует бизнес-объекту. Этот объект имеет свойства, которые относятся к различным способам фильтрации / поиска в списке таких бизнес-объектов. В настоящее время у этих объектов Filter есть метод, который создает содержимое предложения where, которое затем передается в хранимую процедуру SQL Server 2000, где оно объединяется с остальной частью запроса select. Окончательная строка затем выполняется с использованием Exec .

В настоящее время это работает нормально, за исключением проблемы с производительностью из-за отсутствия кэширования плана выполнения. В некоторых исследованиях я видел использование вызова sp_executesql ; это лучшее решение или есть что-то лучше, чем я занимаюсь?

Обновление: Я думаю, что часть проблемы с использованием sp_executesql заключается в том, что на основе коллекции в моем фильтре мне нужно сгенерировать список операторов OR. Я не уверен, что «параметризованный» запрос будет моим решением.

пример

    var whereClause = new StringBuilder();
    if (Status.Count > 0)
    {
       whereClause.Append("(");
       foreach (OrderStatus item in Status)
       {
          whereClause.AppendFormat("Orders.Status = {0} OR ", (int)item);
       }          

       whereClause.Remove(whereClause.Length - 4, 3);
       whereClause.Append(") AND ");
    }

Ответы [ 5 ]

3 голосов
/ 18 июня 2009

Да, sp_executesql будет "кэшировать" план выполнения запроса, который он выполняет.

В качестве альтернативы, вместо передачи части запроса в хранимую процедуру, построения там полного запроса и выполнения динамического SQL, вы можете построить весь запрос на стороне .NET и выполнить его с помощью объекта команды ADO.NET. Все запросы, выполняемые через ADO.NET, по умолчанию «кэшируются».

3 голосов
/ 18 июня 2009

sp_executesql лучше, чем exec из-за повторного использования плана, и вы можете использовать параметры, которые помогают против внедрения SQL. sp_executesql также не вызовет раздувания кэша процедур при правильном использовании

взгляните на эти две статьи

Избегайте преобразований в планах выполнения, используя sp_executesql вместо Exec

Изменение exec на sp_executesql не дает никакой выгоды, если вы не используете параметры правильно

1 голос
/ 18 июня 2009

Вы должны использовать sp_executesql просто потому, что, как вы говорите, план запроса сохраняется и будущие исполнения будут оптимизированы. Также обычно кажется, что он обрабатывает динамический sql лучше, чем execute.

0 голосов
/ 18 июня 2009

sp_executesql - лучший вариант. Рассматривали ли вы не использовать хранимую процедуру для этого или, по крайней мере, удалить некоторые из динамики? Я думаю, что это будет гораздо безопаснее от любого рода инъекций. Я пишу фильтры так же, как вы говорите, но я стараюсь позаботиться о вводе в моем коде, а не о хранимой процедуре. Мне действительно нравится динамический sql, но, может быть, иногда безопаснее пройти лишнюю милю.

0 голосов
/ 18 июня 2009

Современные СУБД (не могу точно сказать, следует ли считать SQL Server 2000 «современным») оптимизированы для специальных запросов, поэтому прирост производительности незначителен (если есть) Что меня беспокоит, так это то, что вы используете sproc для создания динамического SQL: это огромная отладка / поддержка PITA.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...