Las mejores prácticas para la inserción/actualización de gran cantidad de datos en SQL Server 2008

StackOverflow https://stackoverflow.com/questions/2342006

Pregunta

Estoy construyendo un sistema para la actualización de grandes cantidades de datos a través de distintas CSV alimenta.Normalmente sólo quiero bucle pesar de que cada fila de la alimentación, hacer una consulta de selección para comprobar si el elemento ya existe y de inserción/actualización de un elemento en función de si existe o no.

Siento que este método no es muy escalable y podría martillo el servidor en grandes fuentes.Mi solución es un bucle a través de los elementos de forma normal, pero los almacena en la memoria.A continuación, para cada 100 o más elementos de realizar una selección de los 100 elementos y obtener una lista de los elementos existentes en la base de datos que coinciden.Luego concatenar la inserción/actualización de las declaraciones juntos y ejecutar en la base de datos.Esto esencialmente reducir los viajes a la base de datos.

Es esta una solución escalable de una cantidad suficiente de solución y hay algún ejemplo de tutoriales sobre la importación de grandes se alimenta en un entorno productivo?

Gracias

¿Fue útil?

Solución

Al ver que se está utilizando SQL Server 2008, recomendaría este enfoque:

  • primera bulkcopy sus archivos CSV en una tabla de ensayo
  • actualizar la tabla de destino de esa tabla de ensayo utilizando el comando MERGE

Consulte el MSDN docs y una gran blog publicar sobre cómo utilizar el comando MERGE.

Básicamente, se crea un vínculo entre la tabla de datos actual y la tabla de ensayo en un criterio común (por ejemplo, una clave principal común), y luego se puede definir lo que hay que hacer cuando

  • las filas coinciden, por ejemplo, la fila existe en el origen y en la tabla de destino -> general que le sea de actualizar algunos campos, o simplemente ignora todos juntos
  • la fila de la fuente no existe en el objetivo -> típicamente un caso para una inserción

tendría una declaración MERGE algo como esto:

MERGE TargetTable AS t
USING SourceTable AS src
ON t.PrimaryKey = src.PrimaryKey

WHEN NOT MATCHED THEN
  INSERT (list OF fields)
  VALUES (list OF values)

WHEN MATCHED THEN
  UPDATE
    SET (list OF SET statements)
;

Por supuesto, la cláusula ON puede ser mucho más involucrados si es necesario. Y, por supuesto, sus estados de WHEN también pueden ser más complejos, por ejemplo.

WHEN MATCHED AND (some other condition) THEN ......

y así sucesivamente.

MERGE es una nueva muy potente y muy útil de comandos en SQL Server 2008 - lo utilizan, si es posible

Otros consejos

Su forma es la peor solución posible. En general, no se debe pensar en términos de bucle a través de los registros de forma individual. Solíamos tener una herramienta de importación construida compañía que recorre los registros, se necesitarían 18-20 horas para cargar un archivo con más de un millón de discos (algo que no era un fenómeno frecuente cuando fue construido, pero que es un momento más de una día ocurrencia ahora).

Veo dos opciones: En primer inserto uso mayor de la carga a una mesa puesta en escena y hacer lo que la limpieza que hay que hacer en esa mesa. ¿Cómo está determinando si el registro ya existe? Usted debe ser capaz de construir una actualización basada en conjunto por unirse a la tabla de etapas en aquellos campos que determinan la actualización. A menudo tengo un añadido una columna a la tabla de etapas para el ID del registro que coincide con pobladas y que a través de una consulta a continuación, realiza la actualización. Entonces haces una inserción de los registros que no tienen un identificador correspondiente. Si usted tiene demasiados registros que hacer todo a la vez, es posible que desee ejecutar en lotes (que sí es un bucle), pero hacer los lotes considerablemente mayor que 1 registro a la vez (por lo general comienzan con 2000 y luego en base a la el tiempo que le toma a las que determinan si puedo hacer más o menos en el lote).

Creo que 2008 también tiene una declaración de combinación, pero aún no he tenido la oportunidad de usarlo. Búsquelo en libros en línea.

La alternativa es usar SSIS que está optimizado para la velocidad. SSIS es una cosa compleja y aunque la curva de aprendizaje es empinada.

Una forma es cargar su CSV en un DataTable (o más probablemente un DataReader) y luego golpe por lotes en los resultados utilizando SqlBulkCopy -

http://msdn.microsoft.com /en-us/library/system.data.sqlclient.sqlbulkcopy.aspx

Es bastante eficiente y se puede hacer un poco de correlación de columnas. Consejo - cuando asigna columnas utilizando SqlBulkCopy son mayúsculas y minúsculas

.

Otro enfoque sería escribir un procedimiento almacenado en el servidor Net en el servidor para operar en todo el archivo ...

Sólo si necesita más control que la solución de Kris Krause aunque - Soy un gran fan de hacer que sea sencillo (y reutilizable) en lo que podamos ...

Qué se necesita para ser rodar su propio aquí a todos?Sería posible para proporcionar los datos, de tal forma que el SQL Server puede utilizar la Importación Masiva a la carga en y, a continuación, tratar con duplicados en la base de datos una vez finalizada la importación?

Cuando se trata de levantar objetos pesados con una gran cantidad de datos de mi experiencia tiende a ser que el trabajo en la base de datos tanto como sea posible, es mucho más rápido y menos consumo de recursos.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top