Почему «Выбрать * в целевой таблице из исходной таблицы» быстрее, чем «вставить в целевой таблице выбор * из исходной таблицы»


9

Это название вопроса. Мне любопытно узнать ответ. Кто-то сказал

Вхождение в минимально зарегистрировано в Базе данных модели простого восстановления ... Я вообще в нее не попал.

Выдержка из Microsoft:

Объем ведения журнала для SELECT ... INTO зависит от модели восстановления, действующей для базы данных. В рамках простой модели восстановления или модели восстановления с массовой регистрацией массовые операции регистрируются минимально. При минимальном ведении журнала использование оператора SELECT… INTO может быть более эффективным, чем создание таблицы с последующим заполнением таблицы оператором INSERT.

Ищу помощь

Спасибо


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

Я был бы удивлен, если бы была какая-то разница в хорошо написанной СУБД.

База данных: Sql server 20005 ... и я слышал это ... даже я не уверен на 100% ... Я ищу то, что говорят другие народы .. Как я уже говорил, кто-то сказал мне это ...

Нашел ссылку, подтверждающую, что SELECT INTOможно минимально регистрироваться, когда не используется полное восстановление.
Damien_The_Unbeliever

Ответы:


10

Пара идей / теорий:

SELECT INTO ... позволяет СУБД определять порядок сортировки на основе порядка исходной таблицы. Если вы вставляете в существующую таблицу, может потребоваться сортировка, соответствующая кластерному или некластерному индексу (-ам).

Нет индексов - если вы, SELECT INTO...СУБД, наверняка знаете, нет никаких ранее существующих индексов для обновления.

Нет конфликтов - поскольку таблица, в которую вы вставляете, не существует, SQL Server не нужно беспокоиться о блокировке на уровне строк или обработке конфликтов. Ничто другое не может ссылаться на созданную вами таблицу, так как она не существует.

Все это, как говорится, есть другие способы очень быстро вставить в таблицу.

  • Убедитесь, что ваши ключи кластерного индекса совпадают, когда это возможно. Это означает, что нет сортировки на лету

  • Отключить все некластеризованные индексы. Интуитивно понятный.

  • Установите режим восстановления на простой и отметьте флаг 610 на ON. Используйте TABLOCKподсказку на вашей целевой таблице и NOLOCKподсказку на исходной таблице.

Например, предположим, что tablea и tableb имеют одинаковый кластеризованный индекс:

INSERT INTO TableB WITH (TABLOCK)
SELECT <Columns>
FROM TableA WITH (NOLOCK)

По моему опыту, это быстрее, чем использовать SELECT INTO...и затем создавать кластерный индекс впоследствии. Обратите внимание, что это также может работать с таблицей, в которой уже есть данные, что является гораздо более полезным сценарием.

РЕДАКТИРОВАТЬ:

Вот фантастически подробный документ от MS по производительности загрузки данных в Sql Server 2008.


3
Очень подробный ответ JNK. Кроме того, при правильной реализации и неполной модели восстановления простая задача потока данных служб SSIS может выполняться быстрее, чем любая из них. Почему? Оба из вышеперечисленных будут выдавать эксклюзивную блокировку (чтение многопоточное, но запись однопоточное). Пока с табличным адаптером используется блокировка таблицы, SSIS будет использовать блокировку массового обновления (и чтение, и запись являются многопоточными).
Брайан
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.