Por qué "Seleccionar * en la tabla de destino desde la fuente" es más rápido que "insertar en la tabla de destino seleccionar * desde la fuente

9

Este título es la pregunta. Tengo curiosidad por saber la respuesta. Alguien dijo

seleccionar en está mínimamente registrado en la base de datos del modelo de recuperación simple ... No lo hice en absoluto.

Extracto de Microsoft:

La cantidad de registro para SELECT ... INTO depende del modelo de recuperación vigente para la base de datos. Bajo el modelo de recuperación simple o el modelo de recuperación de registro masivo, las operaciones masivas se registran mínimamente. Con un registro mínimo, usar la instrucción SELECT ... INTO puede ser más eficiente que crear una tabla y luego llenar la tabla con una instrucción INSERT

Buscando ayuda

Gracias


fuente
¿Qué base de datos está utilizando? ¿Qué estructuras son las tablas? ¿Cómo midiste que uno es más rápido que el otro?
Me sorprendería si hubiera alguna diferencia en un DBMS bien escrito.
Base de datos: servidor SQL 20005 ... y escuché esto ... aunque no estoy 100% seguro ... Estoy buscando lo que dicen otras personas ... Como mencioné que alguien me dijo esto ...
Encontré un enlace que confirma que SELECT INTOse puede registrar mínimamente cuando no se usa la Recuperación completa.
Damien_The_Unbeliever

Respuestas:

10

Un par de ideas / teorías:

SELECCIONAR EN ... permite que el RDBMS determine el orden de clasificación según el orden de su tabla original. Si inserta en una tabla existente, puede ser necesaria una clasificación para que coincida con un índice agrupado o no agrupado.

Sin índices : cuando SELECT INTO...RDBMS sabe con certeza que no hay índices preexistentes para actualizar.

Sin contención : dado que la tabla en la que está insertando no existe, SQL Server no necesita preocuparse por el bloqueo de nivel de fila o el manejo de contención. Nada más puede hacer referencia a la tabla que crea, ya que no existe.

Dicho todo esto, hay otras formas de insertar en una tabla muy rápidamente.

  • Asegúrese de que sus claves de índice agrupadas coincidan cuando sea posible. Esto significa que no hay clasificación sobre la marcha

  • Deshabilite todos los índices no agrupados. Autoexplicativo.

  • Establezca el modo de recuperación en simple y marque el indicador 610 en ON. Use la TABLOCKpista en su tabla de destino y la NOLOCKpista en su tabla de origen.

Por ejemplo, suponga que tablea y tableb tienen el mismo índice agrupado:

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

En mi experiencia, esto es más rápido que usar SELECT INTO...y luego crear el índice agrupado. Tenga en cuenta que esto también puede funcionar en una tabla que ya tiene datos, lo cual es un escenario mucho más útil.

EDITAR:

Aquí hay un documento técnico increíblemente detallado de MS para el rendimiento de carga de datos en Sql Server 2008.

JNK
fuente
3
Respuesta muy completa JNK. Además, cuando se implementa correctamente y el modelo de recuperación no está lleno, una simple tarea de flujo de datos SSIS puede ser más rápida que cualquiera de estas. ¿Por qué? Ambos de los anteriores emitirán un bloqueo exclusivo (la lectura es multihilo pero la escritura es única). Siempre que se use un bloqueo de tabla con el adaptador de destino, SSIS usará un bloqueo de actualización masiva (tanto la lectura como la escritura son multihilo).
Brian