¿Qué es mejor para grandes cambios en una tabla: BORRAR e INSERTAR cada vez o ACTUALIZAR existente?


27

Estoy haciendo un proyecto donde necesito cambiar alrededor de 36K registros en una tabla diariamente. Me pregunto qué funcionará mejor:

  1. eliminar filas e insertar nuevas, o
  2. actualizar filas ya existentes

Para mí es más fácil simplemente eliminar todas las filas e insertar nuevas, pero si esto va a fragmentar la tabla y los índices y afectar el rendimiento, preferiría realizar actualizaciones cuando sea posible y eliminar / insertar solo cuando sea necesario.

Este será un servicio nocturno y no estoy buscando mejorar la velocidad del proceso en sí. Me preocupa más el rendimiento de las consultas en esta tabla en general, donde ya tengo 89 millones de registros y cómo este proceso nocturno lo afectará.

¿Debo eliminar / insertar registros o debo actualizar los existentes (cuando sea posible) para este proceso nocturno?


Creo que debería dar más detalles sobre su tabla, ya que supongo que dependería de la posible existencia de índices en los campos.
SRKX

Respuestas:


9

Realmente depende de cuánto están cambiando los datos. Digamos que esta tabla tiene 20 columnas. Y también tiene 5 índices, cada uno en un diff. columna.

Ahora, si los valores en las 20 columnas están cambiando O incluso si los datos en 5 columnas están cambiando y estas 5 columnas están todas indexadas, entonces es mejor que "borre e inserte". Pero si solo 2 columnas están cambiando y digamos que no forman parte de ningún índice no agrupado, entonces es mejor que "actualice" los registros porque en este caso solo se actualizará el índice agrupado (y los índices no tendrán que estar actualizado).


En una investigación adicional, descubrí que el comentario anterior de mí es algo redundante ya que SQL Server tiene internamente 2 mecanismos separados para realizar una ACTUALIZACIÓN. - Una "actualización local" (es decir, cambiando el valor de una columna a una nueva en la fila original) o como una "ACTUALIZACIÓN no local" (ELIMINAR seguido de un INSERTAR).

Las actualizaciones en el lugar son la regla y se realizan si es posible. Aquí las filas permanecen exactamente en la misma ubicación en la misma página en la misma extensión. Solo se modifican los bytes afectados. El tlog solo tiene un registro (siempre que no haya activadores de actualización). Las actualizaciones ocurren en el lugar si se está actualizando un montón (y hay suficiente espacio en la página). Las actualizaciones también ocurren en el lugar si la clave de agrupación cambia pero la fila no necesita moverse en absoluto.

Por ejemplo: si tiene un índice agrupado en el apellido y tiene los nombres: Able, Baker, Charlie Ahora desea actualizar Baker a Becker. No se deben mover filas. Entonces esto puede tener lugar. Mientras que, si tiene que actualizar Able a Kumar, las filas deberán desplazarse (aunque estarán en la misma página). En este caso, SQL Server hará un DELETE seguido de un INSERT.

Teniendo en cuenta lo anterior, sugeriría que haga una ACTUALIZACIÓN normal y deje que SQL Server descubra la mejor manera de hacerlo internamente.

Para obtener más detalles sobre los componentes internos de "ACTUALIZACIÓN" o, para el caso, los componentes internos relacionados con SQL Server, consulte el libro de Kalen Delaney, Paul Randal, et al. - Componentes internos de SQL Server 2008 .


8

¿Has investigado el comando MERGE en SQL 2008? Aquí hay un ejemplo básico:

  merge YourBigTable ybt
  using (select distinct (RecordID) from YourOtherTable) yot
     on yot.Recordid = YBT.RecordID
  when NOT matched by target
  then  insert (RecordID)
        values (yot.DeviceID) ;

Esto es básicamente un comando "UPSERT". Actualice si existe, insértelo si no existe. Muy rápido, comando muy bueno.


1
No es más rápido que una ACTUALIZACIÓN, la misma mecánica debajo del capó.
Mark Storey-Smith

Es más rápido que actualizar e insertar los que aún no existían.
datagod

2
Si sabes que ese es el caso, pruébalo :)
Mark Storey-Smith

4

Pero, yo mismo verifiqué Eliminar e Insertar vs Actualizar en una tabla que tiene 30 millones de registros (3crore). Esta tabla tiene una clave compuesta única agrupada y 3 claves no agrupadas. Para Eliminar e Insertar, tomó 9 min. Para la actualización tomó 55 min. Solo se actualizó una columna en cada fila.

Entonces, les pido a las personas que no adivinen. Las ecuaciones cambiarán cuando se trate de una tabla grande con muchas columnas y con muchos datos.


También llegué a este caso, pero luego descubrí que a veces es posible optimizar una fusión grande agregando indicaciones (temp o perm) al origen o destino, sugerencias o subconfigurando el objetivo (no aplicable para la fusión completa).
crokusek

3

La actualización no es tan rápida. El truco es lograr una inserción rápida es deshabilitar los índices mientras se insertan los datos.

Considere usar esto:

-- disable indexes
ALTER INDEX [index_name] ON dbo.import_table DISABLE
-- ... disable more indexes

-- don't use delete if you don't care about minimal logging. truncate is faster
TRUNCATE TABLE dbo.import_table

-- just insert the new rows
INSERT dbo.import_table
SELECT
    *
FROM
    dbo.source_table

-- rebuild indexes
ALTER INDEX [index_name] ON dbo.import_table REBUILD
-- ... rebuild more indexes

Incluso más rápido es desactivar también la actualización automática de estadísticas en las opciones de db. Si la tabla cambia significativamente, debe ejecutar:

UPDATE STATISTICS dbo.import_table

o

EXEC sp_updatestats

como trabajo de forma regular (diariamente, semanalmente dependiendo del tamaño de la base de datos) para mantener las estadísticas actualizadas. Lo que hay que tener en cuenta es actualizar las estadísticas cuando la tabla está vacía. Eso arruinará las estadísticas si no lo ejecuta después de que la tabla se haya llenado nuevamente.


44
No estoy de acuerdo con que este sea siempre el caso. Además, TRUNCATE no puede borrar la tabla de la pregunta de @ adopilot, ya que contiene 89 millones de registros y solo desea actualizar 36k.
Mark Storey-Smith

Necesito aprender a leer el post con más cuidado! actualizaré la publicación ... en realidad, necesito cambiar mucho.
Asken
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.