2011-08-17 20 views
10

Estoy realizando algunas pruebas en el servidor SQL y quiero obtener la mejor velocidad de inserción posible. La declaración que utilizo es algo como esto:Velocidad de inserción Sql

INSERT INTO db_Test_databse..tbl_test with(rowlock) 
    ( joinid, date_key, 
     col1, col2,col3,col4, col5, col6, col7, col8, col9, col10, ...  
    ) 

SELECT tabid as joinid, 
     date_key, 
     rec_type, 
     col2, 
     dbo.udf_convert_hex_to_dec(col3), 
     col4, col5, col6, col7, col8, 
     dbo.udf_convert_hex_to_dec(col9), 
     dbo.udf_convert_hex_to_dec(col10), 
     ... 
from source_table f 

hay 25 columnas; la mayoría de ellos son de tipo bigint o int.

He descartado todos los índices de la tabla de destino excepto la clave principal, que es un campo de identidad.

¿Algún consejo sobre cómo mejorar el rendimiento más?

P.s. De esta forma, tengo una velocidad promedio de 16,000 filas/seg.

+0

'dbo.udf_convert_hex_to_dec' te está matando. ¿Qué versión de SQL Server estás usando? Hay integradas para hacer esta conversión. – Yuck

+0

Estoy mirando sospechosamente la función 'udf_convert_hex_to_dec'. Los insertos solo se pueden hacer más rápido hasta cierto punto, algunos factores son índices y el rendimiento físico de IO.Ejecutar un analizador de consultas en su contra, apuesto a que la selección es la parte lenta debido a la función. –

+2

Las funciones definidas por el usuario pueden ser lentas. ¿No puedes lanzar el hex directamente a decimal - CAST (col9 AS Decimal (4)) por ejemplo>? – Simon

Respuesta

14

Para obtener el mejor rendimiento posible debe:

  • Retire todos los activadores y las restricciones sobre la mesa
  • Retire todos los índices, a excepción de los necesarios por el inserto
  • asegurar que su índice agrupado es tal que siempre se insertarán nuevos registros al final de la tabla (una columna de identidad funcionará bien). Esto evita divisiones de página (donde SQL Server debe mover datos porque una página existente está llena)
  • Establezca fill factor en 0 o 100 (son equivalentes) para que no quede espacio en la tabla vacío, reduciendo el número de páginas que los datos están distribuidos
  • Cambie el recovery model de la base de datos a Simple, reduciendo la sobrecarga para el registro de transacciones.

¿Hay varios clientes que insertan registros en paralelo? Si es así, entonces también debes considerar las implicaciones de bloqueo.

Tenga en cuenta que SQL Server puede sugerir índices para una consulta determinada ya sea by executing the query in SQL Server Management Studio o a través del Database Engine Tuning Advisor. Debería hacer esto para asegurarse de no haber eliminado un índice que SQL Server estaba utilizando para acelerar el INSERT.

Si esto todavía no es lo suficientemente rápido, entonces debería considerar la agrupación hasta insertos utilizando un BULK INSERT lugar (o algo así como el bcp utility o SqlBulkCopy, ya que ambos utilizan BULK INSERT bajo las sábanas). Esto proporcionará el mayor rendimiento al insertar filas.

Ver también Optimizing Bulk Import Performance - muchos de los consejos en ese artículo también se aplican a las inserciones "normales".

+0

Como dije, tengo solo un índice que es la clave principal y no disparadores. Intentaré usar el método BULK INSERT. –

+0

Ordene la consulta de origen al índice agrupado en el destino. – Paparazzi

+0

En lugar de cambiar el modelo de recuperación a Simple, cámbielo a [BULK_LOGGED] (http://msdn.microsoft.com/en-us/library/ms189275 (v = sql.110) .aspx). Puede volver a cambiarlo después de la operación masiva. – CFreitas

1

¿Ha considerado utilizar SqlBulkCopy? Necesita compilar una DataTable y pasarla a la rutina WriteToServer.

¡Es RÁPIDO!

1

se puede utilizar en su proceso de almacenamiento antes de fin

OPTION(RECOMPILE) 
Cuestiones relacionadas