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.
fuente
CXPACKET
esperas: 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.Respuestas:
Lograr un rendimiento de importación óptimo en este escenario requiere tres cosas:
Registro mínimo
Lograr inserciones mínimamente registradas en una tabla agrupada vacía sin índices no agrupados requiere:
SIMPLE
oBULK_LOGGED
TABLOCK
YORDER
sugerencias)Nota al margen:
Crear índices no agrupados por separado
Las ventajas de hacer esto son:
CREATE INDEX
se registra mínimamente si el modelo de recuperación no esFULL
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 BY
clá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
fuente