почему вставка одной строки в x раз быстрее, чем вставка x строк сразу
Возможный дубликат:
Несколько инструкций INSERT против одного INSERT с несколькими значениями VALUES
Я делаю некоторый анализ производительности транзакций для пакетной обработки для сообщения в блоге, и я заметил, что когда вы используете оператор пакетной вставки, он выполняет гораздо медленнее, чем эквивалентные отдельные инструкции SQL.
вставка 1000 строк, как показано ниже, занимает приблизительно 3 с
INSERT TestEntities (TestDate, TestInt, TestString) VALUES ('2011-1-1', 11, 'dsxcvzdfdfdfsa'), ('2011-1-1', 11, 'dsxcvzdfdfdfsa'), ('2011-1-1', 11, 'dsxcvzdfdfdfsa')
вставка 1000 строк, как показано ниже, занимает 130 мс
INSERT TestEntities (TestDate, TestInt, TestString) VALUES ('2011-1-1', 11, 'dsxcvzdfdfdfsa') INSERT TestEntities (TestDate, TestInt, TestString) VALUES ('2011-1-1', 11, 'dsxcvzdfdfdfsa') INSERT TestEntities (TestDate, TestInt, TestString) VALUES ('2011-1-1', 11, 'dsxcvzdfdfdfsa')
Это происходит только в первый раз, когда вы используете пакетную вставку на столе, но ее воспроизводимую.
Также обратите внимание, что вставка данных im является случайной (но то же самое для обоих запросов)
РЕДАКТИРОВАТЬ:
heres мой пример воспроизведения с фиктивными случайными данными, используемыми для этого случая: https://gist.github.com/2489133
Проблема здесь в соответствии с инструкциями Multiple INSERT по сравнению с одиночным INSERT с несколькими значениями VALUES заключается в том, что когда SQL получает запрос, он должен вычислять план запроса при первом выполнении. Для одной вставки это хорошо и быстро, так как вычислять не так много, и после того, как он построил план запроса, он просто повторно использует его 1000 раз.
в пакетном сценарии есть 3k переменных, которые необходимо встроить в план запроса, который занимает намного больше времени для вычисления.
Одна сумасшедшая функция, которую @MartinSmith указывает на то, что есть малый номер производительности вокруг размера партии до 250 строк, что означает, что расчет плана очень низок.
разбиение моего запроса выше на 5 200 операторов строки сокращает время выполнения до 94ms для 1000 строк
Первый элемент – это один большой оператор, который должен быть проанализирован, поэтому дополнительное время, проведенное там, связано с накладными расходами одного крупного синтаксического анализа вместо 1000 маленьких.
Хотя я не тестировал все 1000 строк, я проверил на 3 и обнаружил, что план выполнения для одного оператора вставки больше. Также обратите внимание, что для трех отдельных вставок есть только один маленький план, который используется повторно.
Первый – это один оператор, который запускается как одна транзакция. Второй – 1000 заявлений с накладными расходами в 1000 транзакций. Разница должна уменьшиться, если вы вложите вторую в begin transaction
и commit transaction
.