2011-05-14 38 views
7

Necesito realizar una actualización diaria de un gran (300M registros) y amplio TABLE1. La fuente de datos para las actualizaciones se encuentra en otra tabla UTABLE que es 10% -25% de las filas de TABLE1 pero es estrecha. Ambas tablas tienen record_id como clave principal.ACTUALIZACIÓN o FUSIÓN de tablas muy grandes en SQL Server

Actualmente, estoy recreando TABLE1 utilizando el siguiente enfoque:

<!-- language: sql --> 
    1) SELECT (required columns) INTO TMP_TABLE1 
    FROM TABLE1 T join UTABLE U on T.record_id=U.record_id 
    2) DROP TABLE TABLE1 
    3) sp_rename 'TMP_TABLE1', 'TABLE1' 

Sin embargo esto tiene casi 40 minutos en mi servidor (60 GB de RAM para SQL Server). Quiero lograr un 50% de ganancia de rendimiento. ¿Qué otras opciones puedo probar?

  1. MERGE y UPDATE - algo así como el código de abajo funciona más rápido sólo para una pequeña UTABLE mesa - a tamaño completo, todo lo que acaba cuelga:

    <!-- language: SQL --> 
    MERGE TABLE1 as target 
    USING UTABLE as source 
    ON target.record_id = source.record_id 
        WHEN MATCHED THEN 
        UPDATE SET Target.columns=source.columns 
    
  2. oí que puedo realizar un lote MERGE usando ROWCOUNT, pero no creo que pueda ser lo suficientemente rápido para una mesa de 300M.

  3. ¿Alguna sugerencia de consulta SQL que pueda ser útil?

+0

¿Puede publicar el plan de consulta? –

+0

Hola @chris, el plan de consulta es muy simple: ** 1 ** Escaneo de tabla TABLA1, ** 2 ** Escaneo de tabla UTABLE, ** 3 ** UNIÓN HASH, ** 4 ** FUSIÓN. El primer y último paso están tomando el 90% del tiempo. Sin embargo, ya he entendido cómo abordar mi pregunta, por favor vea mi propia respuesta. –

Respuesta

5

En realidad, he encontrado recomendaciones generales para tales consultas: Idea para usar SQL Merge o Actualización es muy inteligente pero falla cuando tenemos que actualizar muchos registros (es decir, 75M) en una gran y amplia tabla (es decir, 240M).

Mirando el plan de consulta de la consulta a continuación podemos decir que TABLE SCAN de TABLE1 y final MERGE están tomando el 90% de tiempo.

MERGE TABLE1 as Target 
USING UTABLE as source 
ON Target.record_id = source.record_id 
WHEN MATCHED AND (condition) THEN 
    UPDATE SET Target.columns=source.columns 

Así que con el fin de utilizar la combinación necesitamos:

  1. Reducir el número de filas que necesitamos para actualizar y transmitir esta información a SQL Server correctamente. Esto se puede hacer haciendo que UTABLE sea más pequeño o especificando condition que estrecha la parte que se fusionará.
  2. Asegúrese de que la parte que se va a fusionar se ajuste a la memoria, de lo contrario, la consulta se ejecuta mucho más lentamente. Hacer TABLE1 redujo dos veces menos mi tiempo de consulta real de 11 horas a 40 minutos.

Como se mencionó Mark puede utilizar UPDATE sintaxis y el uso WHERE cláusula para limitar parcial a fusionarse-- esto le dará los mismos resultados. Además, evite indexar TABLE1 ya que esto causará trabajo adicional para reconstruir el índice durante MERGE

6

Primero averiguaré dónde está el cuello de botella: ¿está su CPU sujeta o inactiva? En otras palabras, ¿su subsistema IO puede manejar la carga correctamente?

La recreación de la tabla completa implica una gran carga de IO, sin mencionar que ocupará mucho espacio tener básicamente la tabla almacenada dos veces temporalmente.

¿Necesita realizar una fusión? Por lo que puedo ver, una actualización simple debería ser suficiente. Ejemplo:

UPDATE 
    TABLE1 
SET 
    ColumnX = UTABLE.ColumnX 
    ... 
FROM 
    TABLE1 
INNER JOIN 
    UTABLE ON TABLE1.record_id = UTABLE.record_id 

Se podría lotes hasta las actualizaciones mediante ROWCOUNT pero eso no va a acelerar la ejecución, que va sólo para ayudar con la reducción de bloqueo general.

Además, ¿qué tipo de índices tiene sobre la mesa? Puede ser más rápido desactivar los índices antes de la actualización y luego reconstruirlos desde cero después (solo los no agrupados).

+0

Hola Marcos, gracias por la respuesta, no tengo un índice porque simplemente ralentizaría las consultas de MERGE o UPDATE. En cuanto a IO, basado en el contador promedio de la cola de discos, el disco está bastante ocupado y parece que TABLE1 simplemente no cabe en la memoria. Ahora estoy experimentando la entrada de filtrado previo con CTE y solo entonces realizo MERGE y responderé mi propia pregunta con los resultados. –

+1

+1 Gran respuesta. No puedo entender por qué nadie lo votó aún. –

Cuestiones relacionadas