Mejore la velocidad de la reconstrucción del índice en el servidor SQL

9

Estoy importando una gran cantidad de datos en una base de datos vacía, y antes de comenzar deshabilité todos los índices no agrupados no únicos para ver si podía mejorar el rendimiento de la importación.

Ahora quiero volver a habilitar los índices, y me pregunto si hay algo que pueda hacer para optimizar esto.

Hay> 100 tablas y casi 2.000 índices para reconstruir. La base de datos tiene un tamaño de 200 GB.

La sección clave del script que estoy ejecutando es esta:

declare c_toggle_index cursor FORWARD_ONLY READ_ONLY for
    select  'alter index ' + QUOTENAME(i.name) + ' on ' + o.name + ' rebuild'
    from    sys.indexes as i
    Inner Join sys.objects o
    On o.object_id = i.object_id
    Where o.is_ms_shipped = 0
    And i.index_id >= 1
    and i.type > 1
    and i.is_disabled = 1

Pensé en configurar ONLINE = OFF para la instrucción alter index, pero como los índices comienzan deshabilitados, no estaba seguro de que esta configuración tuviera algún efecto. También consideré configurar SORT_IN_TEMPDB = ON, pero como los archivos tempdb están en la misma unidad que los archivos .mdf de las bases de datos, supuse que tampoco había ningún beneficio en hacerlo.

Mientras ejecutaba el script de reconstrucción, noté que tengo muchos tipos de espera CXPACKET. Realmente no entiendo por qué sería eso o si es un problema que debería tratar de resolver.

Un último punto que puede ser relevante: todo mi servidor está actualmente inactivo, aparte de esta importación de datos en la base de datos. No hay otra actividad del usuario para considerar o preocuparse; Mi única preocupación es importar los datos a la base de datos en el menor tiempo posible.

paulH
fuente
3
Cuando dice que su única preocupación es el tiempo de importación, ¿se refiere al tiempo desde el inicio de la importación hasta el final de volver a habilitar los índices? Si es así, solo debe dejar los índices habilitados durante la importación. 2,000 índices para datos de 200GB me parecen muchos índices. Tal vez debería mirar los DMV de uso del índice para ver si hay algunos que podrían eliminarse.
Max Vernon
1
Solo para aclarar, ¿necesita hacer la misma importación de 200 GB repetidamente y no solo una vez?
Jon Seigel
1
Solo necesito hacer la importación una vez, pero como parte de un proceso más grande con una ventana de tiempo limitada, por lo que actualmente estoy probando ese proceso para que encaje dentro de esa ventana. @MaxVernon Parece que tienes razón en que dejar los índices habilitados es la forma más rápida, aunque me sorprende al leer que normalmente era más rápido deshabilitar los índices, importar los datos y luego volver a habilitarlos. Esta es una base de datos de terceros, por lo que no es posible eliminar índices o cambiarla.
Paul
3
Bueno. Acerca de las CXPACKETesperas: el índice se reconstruye a sí mismo escaneando índices (incluso el índice que se está reconstruyendo ), y esos escaneos pueden usar paralelismo. No debe preocuparse por esas esperas: el paralelismo probablemente esté ayudando.
Jon Seigel

Respuestas:

10

Lograr un rendimiento de importación óptimo en este escenario requiere tres cosas:

  1. Inserciones de tabla base mínimamente registradas
  2. Compilaciones de índice no agrupadas mínimamente registradas
  3. Evitar lecturas físicas

Registro mínimo

Lograr inserciones mínimamente registradas en una tabla agrupada vacía sin índices no agrupados requiere:

  1. Usar los modelos de recuperación de base de datos SIMPLEoBULK_LOGGED
  2. Especificar un bloqueo de tabla y una entrada ordenada (p. Ej. TABLOCKY ORDERsugerencias)

Nota al margen:

También es posible lograr inserciones mínimamente registradas en una tabla agrupada que tiene índices no agrupados, siempre que el indicador de rastreo 610 esté habilitado. Si las inserciones de índice no agrupadas se registran mínimamente o no, depende del plan de consulta seleccionado por el optimizador de consultas.

Si el plan de consulta utiliza un iterador separado para el índice no agrupado, y el iterador tiene la DMLRequestSortpropiedad establecida true, las inserciones de índice no agrupado se registrarán mínimamente, siempre que se cumplan las otras condiciones mencionadas anteriormente.

Crear índices no agrupados por separado

Las ventajas de hacer esto son:

  1. Las inserciones de índice agrupadas se pueden registrar mínimamente sin habilitar TF 610
  2. CREATE INDEX se registra mínimamente si el modelo de recuperación no es FULL

Evitar lecturas físicas

Idealmente, los datos que se importarán se almacenarán en una máquina separada, o al menos en un almacenamiento físico separado del utilizado para alojar la base de datos.

El servidor de la base de datos debe tener suficiente memoria para contener la tabla base más grande en caché, con suficiente para las operaciones de clasificación necesarias al crear índices no agrupados.

Un buen patrón es cargar rápidamente la tabla base (carga de índice agrupada mínimamente registrada) y luego construir todos los índices no agrupados para esa tabla mientras sus páginas de datos todavía están en caché.

La pregunta describe un proceso mediante el cual las tablas base se cargan primero y luego se crean los índices no agrupados. La definición del cursor no utiliza una ORDER BYcláusula para agrupar al menos las compilaciones de índice no agrupadas en la misma tabla.

El resultado probable es que las páginas de datos para diferentes tablas se leen repetidamente en la memoria caché y luego se descartan a medida que los índices no agrupados se crean en un orden no determinista.

El costo de las lecturas físicas repetidas domina por completo los beneficios de un registro mínimo obtenido al construir índices no agrupados por separado. Esto explica por qué descubrió que cargar tablas con índices existentes es más rápido (porque todos los índices no agrupados para una tabla determinada se mantienen antes de pasar a la siguiente tabla).

Resumen

El proceso de importación debe modificarse para cargar en masa una tabla a la vez. Esto significa cargar la tabla y crear todos los índices no agrupados antes de pasar al siguiente. La instancia de SQL Server debe tener suficiente memoria disponible para contener la tabla más grande y realizar la clasificación de índice no agrupado más grande al mismo tiempo.

También puede intentar habilitar TF 610 antes de cargar los datos en tablas con índices no agrupados ya en su lugar. Esto no suele ser tan rápido como el método anterior, pero puede ser lo suficientemente rápido.

Consulte lo siguiente para obtener más información:

La guía de rendimiento de carga de datos

Operaciones que se pueden registrar mínimamente

Paul White 9
fuente