Почему использование параметризованного запроса для вставки данных в таблицу быстрее, чем добавление значений в строку запроса? - PullRequest
6 голосов
/ 05 декабря 2009

Почему для вставки данных в таблицу используется параметризованный запрос:

string queryString = "insert into product(id, name) values (@id, @name)";

быстрее, чем добавление значений в строку запроса:

string queryString = "insert into product(id, name) values (" + _id + ", " + _name + ")";

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

Я знаю, что параметризованный запрос имеет преимущества в плане безопасности и удобства обслуживания, и это рекомендуемый способ использования, но теперь меня интересует объяснение, почему он намного быстрее?

Ответы [ 5 ]

8 голосов
/ 05 декабря 2009

В общем, самая дорогая часть выполнения SQL-запроса - это создание плана выполнения - определение таблиц, которые будут необходимы, определение наилучших индексов (если таковые имеются) для использования и т. Д. Вы можете думать об этом как " составление "запроса, если хотите.

Когда вы используете параметризованный запрос, вы можете подготовить его один раз, а затем просто включить другие целевые значения. Поскольку это одна и та же операция с разными данными, нет необходимости каждый раз перестраивать план выполнения. Чтобы расширить метафору «компиляции», это похоже на повторное выполнение одной и той же программы с другим файлом конфигурации.

Однако, когда вы добавляете значения, вы жестко их кодируете в запросе, поэтому его приходится каждый раз пересматривать, и вы несете затраты на создание нового плана выполнения для каждой итерации. Опять же, с метафорой «компиляции», это похоже на программу на C со всей ее жестко заданной конфигурацией - измените один параметр, и вам придется перекомпилировать все это.

(Другая большая цена, с которой вы можете столкнуться при массовых вставках, - это обновление индексов. Если ваша таблица проиндексирована, вы можете попытаться отключить их, выполнить вставки и снова включить их, так что для этого нужно только переиндексировать один раз, а не после добавления каждой строки.)

5 голосов
/ 05 декабря 2009

Simple. Разбор и подготовка плана выполнения для запроса занимает много времени даже до начала выполнения запроса.

Когда вы добавляете параметры в виде текста к запросу, каждый запрос отличается, поэтому БД должна проанализировать его и подготовить план выполнения.

Когда вы используете параметры, вы отправляете один и тот же запрос много раз (с разными данными), и БД может просто повторно использовать план выполнения из более раннего вызова.

В большинстве случаев это просто сравнение текста между запросами. Например, в MS SQL Server достаточно изменить регистр букв или добавить пробел в конце запроса, чтобы заставить БД воссоздать план выполнения.

4 голосов
/ 05 декабря 2009

В зависимости от используемой вами БД, обычная причина в том, что параметризованный запрос должен быть скомпилирован только один раз, а версия динамического запроса перекомпилируется при каждом использовании.

3 голосов
/ 05 декабря 2009

Это связано с тем, что база данных кэширует планы запросов, что делает его более быстрым.

Для сервера Sql см. Это объяснение

Кэширование и повторное использование плана выполнения

0 голосов
/ 28 сентября 2016

Бьюсь об заклад, это не будет быстрее, если вы использовали несколько значений
Вы можете сделать до 1000

string queryString = "insert into product(id, name) values " + 
"   (" + _id  + ", " + _name  + ")" + 
" , (" + _id1 + ", " + _name1 + ")" + 
" , (" + _id2 + ", " + _name2 + ")"; 
...