2010-09-08 5 views
7

Estoy tratando con trozos de datos que son 50k filas cada uno. los estoy insertando en una base de datos SQL utilizando LINQ:Insertos SQL más rápidos?

for(int i=0;i<50000;i++) 
{ 
    DB.TableName.InsertOnSubmit 
    (
     new TableName 
     { 
      Value1 = Array[i,0], 
      Value2 = Array[i,1] 
     } 
    ); 
} 
DB.SubmitChanges(); 

esto toma aproximadamente 6 minutos, y quiero que tome mucho menos si es posible. ¿Alguna sugerencia?

+0

¿Ha realizado un perfil para ver dónde pasa la mayor parte del tiempo? –

+0

¡13,88 insertos por segundos parecen rendimientos muy pobres! ¿Cuál es tu base de datos? –

+0

He hecho un perfil muy primitivo en todo mi programa y la inserción está tomando el 95% del tiempo.No he perfilado dentro de la inserción. – sooprise

Respuesta

10

Si está leyendo en un archivo, sería mejor usar BULK INSERT (Transact-SQL) y si está escribiendo tanto (50K filas) de una vez desde la memoria, es mejor que primero escriba en un archivo plano y luego use Inserción masiva en ese archivo.

+0

¡Estoy totalmente de acuerdo! – Stefan

+4

Aboslutely, el problema es 50K inserciones individuales vice una inserción masiva, esta es una tarea que simplemente no debería considerar el uso de LINQ para hacer. Esto es algo que debe hacerse en un conjunto. BULK insert debería eliminar esto en mucho menos de un minuto, solía insertar 21 millones de registros en 16 minutos en un viejo servidor lento. – HLGEM

+0

¿En qué formato debe estar el archivo de datos? ¿Puedo simplemente separar los valores? – sooprise

1

Como está haciendo una inserción simple y no gana mucho con el uso de LinqToSql, eche un vistazo a SqlBulkCopy, eliminará la mayoría de los viajes redondos y reducirá la sobrecarga en el lado del servidor Sql. Deberá realizar muy pocos cambios de codificación para usarlo.

Consulte también la clasificación previa de sus datos por la columna en la que se indexa la tabla, ya que esto generará mejores coincidencias cuando el servidor SQL actualice la tabla.

Considere también si debe cargar los datos en una tabla de etapas temp que no esté indexada, luego un proceso almacenado para insertar en la tabla principal con una única instrucción sql. Este puede dejar que SqlServer extienda el trabajo de indexación sobre todas sus CPU.

1

Hay muchas cosas que debe verificar/hacer.

  1. ¿Cuánto espacio en disco está asignado a la base de datos? ¿Hay suficiente libertad para hacer todas las inserciones sin que aumente automáticamente el tamaño? De lo contrario, aumente el tamaño del archivo de la base de datos, ya que tiene que detener todas las inserciones para cambiar automáticamente el tamaño de la base de datos.

  2. NO haga insertos individuales. Toman mucho tiempo. En su lugar, utilice los parámetros de valor de tabla (sql 2008), sql bulk copy o una sola instrucción de inserción (en ese orden de preferencia).

  3. suelte los índices en esa tabla antes y recíclelos después de la carga. Con tantos insertos, probablemente los destrozarán al infierno.

  4. Si tiene algún disparador, considere dejarlo caer hasta que la carga se complete.

  5. ¿Tiene suficiente RAM disponible en el servidor de la base de datos? ¿Necesita verificar el servidor para ver si está consumiendo TODA la RAM disponible? Si es así, podría considerar reiniciar antes de la carga ... el servidor sql tiene una tendencia a consumir y aferrarse a todo lo que puede conseguir.

  6. A lo largo de las líneas de RAM, nos gusta mantener suficiente memoria RAM en el servidor para mantener toda la base de datos en la memoria. No estoy seguro de si esto es factible para usted o no.

  7. ¿Cómo es la velocidad del disco? ¿La profundidad de la cola es bastante larga? Aparte del reemplazo de hardware, no hay mucho que hacer aquí.

Cuestiones relacionadas