Tengo una base de datos SQL que está alojada en Azure. El problema es que el tamaño se está descontrolando, puedo ver hasta un 99% de fragmentación en los índices agrupados de la clave primaria.
Puedo reconstruir todos los demás índices con la online=on
opción y no afectará el rendimiento. El tamaño de uno de los índices de PK Clustered es superior a 200 GB, y para este REBUILD...WITH (ONLINE=ON)
causa un bloqueo.
Tenemos usuarios de todas las zonas horarias que acceden al sitio, así que realmente, no puedo encontrar un momento en el que pueda reconstruir el índice sin conexión.
¿Cuál es la mejor estrategia para reconstruir índices grandes sin tener un tiempo de inactividad en el sitio?
Creo que reorganizar no ayudará, ya que la fragmentación es del 99%. El problema es que la mesa se bloquea incluso en línea. El principal problema es que el índice es superior a 200 GB. La clave primaria es un entero.
REORGANIZE
reducirá la fragmentación de la página de la hoja y el espacio compactoREBUILD
, de manera menos eficiente. ¿Estás seguro de que el gran tamaño se debe a la fragmentación? ¿Cuál es el factor de relleno?Respuestas:
Aunque es un poco tarde, responderé con la esperanza de que ayude o al menos rechace algunas ideas / comentarios adicionales sobre este tema porque creo que es una buena pregunta.
Primero, y no sé si está haciendo esto o no, pero no asuma que los altos niveles de fragmentación en el índice siempre causarán un bajo rendimiento. Las estadísticas obsoletas (por ejemplo, sys.dm_db_stats_properties ) y grandes cantidades de espacio en blanco por página (es decir, la columna avg_page_space_used_in_percent en sys.dm_db_index_physical_stats dmv ) tienen más relevancia con respecto a los problemas de rendimiento que la fragmentación sola. Sí, los índices altamente fragmentados generarán más puntos de lectura y, por lo general, verá estadísticas obsoletas y niveles más altos de espacio en blanco por página junto con la fragmentación, pero la fragmentación no está directamente vinculada a las optimizaciones del plan de consulta ni a la cantidad de memoria que carga el índice desde el disco realmente consumirá Los planes de consulta se ven afectados por las estadísticas y su huella de memoria se hincha con más espacio en blanco . Por ejemplo, un índice que está 99% fragmentado pero tiene menos de 5% de promedio. el espacio en blanco y las estadísticas actualizadas probablemente no le causen problemas drásticos de rendimiento en comparación con un mal plan de ejecución como resultado de estadísticas obsoletas o paginación constante de un índice que es demasiado grande para caber completamente en la memoria porque hay una cantidad significativa de espacio en blanco presente por página.
Si la fragmentación es realmente un problema , puede reducirla, EN LÍNEA, emitiendo una
ALTER INDEX ... REORGANIZE
declaración identificada por Dan Guzman en los comentarios. Esto no creará un índice tan ágil como loREBUILD
hará una operación, pero reducirá su fragmentación. La clave aquí es identificar ventanas de menor uso en su base de datos y ejecutarlas luego. Esto podría ser de 15 minutos o varias horas, obviamente, cuanto más tiempo mejor, pero la clave aquí es que esta operación no retrocede y retiene cualquier progreso realizado incluso si lo matas a mitad de la ejecución.Si, en un mundo perfecto donde se eliminó su fragmentación, ¿ tendría más sentido utilizar la partición en esta tabla? Azure SQL Database permite la partición de tablas y Microsoft tiene un excelente artículo que describe algunas estrategias de Particionamiento para Azure SQL Database . Si sus datos no son volátiles, particionarlos puede ayudar a reducir las necesidades de mantenimiento, y si se combina con Table Compression , incluso puede reducir su huella de almacenamiento general. La respuesta anterior de Alberto Murillo alude a la utilización de particionamiento horizontal basado en una región de datos, y este enfoque puede ayudar a crear algunas ventanas de mantenimiento para usted, ya que sus datos serían más específicos regionalmente en lugar de global.
La transición a una tabla particionada no será fácil con su ausencia actual de ventanas de mantenimiento, pero es posible que pueda utilizar un enfoque descrito por Maria Zakourdaev que utiliza vistas particionadas sobre la parte superior de su tabla actual y una nueva tabla particionada para iniciar la partición datos futuros A medida que pasa el tiempo (y es de esperar que se eliminen sus datos antiguos), con el tiempo puede pasar completamente a la tabla particionada. Nuevamente, no conozco sus datos o aplicación, pero quizás este enfoque sea algo que pueda emplear.
fuente
Primero, es importante considerar si la fragmentación es importante.
Si su consulta solo realiza búsquedas de una sola fila, es posible que no note ninguna fragmentación. En las SAN modernas, el almacenamiento en caché a nivel de SAN puede hacer que las E / S físicas sean lo suficientemente rápidas como para que la fragmentación no importe. En SSD, el patrón de E / S aleatorio causado por el escaneo de un índice fragmentado en realidad puede resultar en un mejor rendimiento que los datos no fragmentados.
Muchas veces, las personas notan que reconstruir un índice solucionó un problema de rendimiento. La reconstrucción de un índice también genera estadísticas nuevas. Puede darse el caso de que la solución real sean estadísticas nuevas, no la reconstrucción del índice.
UPDATE STATISTICS...WITH FULLSCAN
puede ser una forma más barata, más rápida y menos intrusiva de resolver el mismo problema de rendimiento.Si no tiene problemas causados por la fragmentación, podría estar gastando mucho tiempo y esfuerzo sin obtener ganancias reales.
En segundo lugar, hay dos tipos de fragmentación:
Fragmentación física Esto es lo que piensa la mayoría de la gente cuando piensa en la fragmentación. Las páginas están fuera de servicio y deben reordenarse. Al escanear un índice, este tipo de fragmentación a veces puede ser un problema. En general, he notado que esto tiene el mayor impacto en el rendimiento con lecturas físicas . Si está viendo los resultados
sys.dm_db_index_physical_stats
, este número es laavg_fragmentation_in_percent
columna.Fragmentación de baja densidad. Esta fragmentación es causada por páginas que solo están parcialmente llenas de datos. Tiene baja densidad de datos porque sus datos se distribuyen en más páginas de las necesarias. Como resultado, leer los datos requiere más E / S porque los datos se distribuyen en más páginas de las necesarias. Esto puede afectar tanto las lecturas lógicas como físicas. Si está viendo los resultados
sys.dm_db_index_physical_stats
, este número es laavg_page_space_used_in_percent
columna. Esta columna solo se completa cuando se usa el modoSAMPLED
oDETAILED
.Entonces, ¿qué haces al respecto?
Fragmentación física : si simplemente persigue números altos
avg_fragmentation_in_percent
, considere realmente si está perdiendo el tiempo. Asegúrese de tener una consulta real que tenga un rendimiento deficiente y use un entorno de prueba para confirmar que está solucionando un problema eliminando la fragmentación.Puede abordar la fragmentación física haciendo
ALTER INDEX...REORGANIZE
. LaREORGANIZE
operación está en línea, moviendo las páginas de una en una para reorganizarlas nuevamente en orden físico. Si elimina unaREORGANIZE
declaración a mitad de camino, cualquier trabajo que ya se haya realizado se mantiene: solo se revertirá la página que se está moviendo actualmente. Hacer unaREORGANIZE
tabla grande que esté muy fragmentada puede requerir más espacio total de registro de transacciones, y en modo de recuperación completa puede generar una cantidad significativa de copias de seguridad del registro de transacciones. También puede llevar más tiempo paraREORGANIZE
un índice altamente fragmentado que paraREBUILD
él.A menudo verá consejos para realizar un
REBUILD
índice altamente fragmentado, en lugar de unREORGANIZE
: esto se debe a que la reconstrucción desde cero puede ser más eficiente. Sin embargo, la reorganización puede ser una operación "más en línea" y a veces se prefiere, incluso para índices altamente fragmentados.La fragmentación de baja densidad no puede ser reparada por
REORGANIZE
. Solo se puede solucionar haciendo unALTER INDEX...REBUILD
. Al hacer el índice conONLINE=ON
, debería poder minimizar el bloqueo. Sin embargo,REBUILD
todavía necesita tomar un candado por un momento para intercambiar el índice antiguo por el nuevo índice. En un sistema muy ocupado, lograr este bloqueo exclusivo a veces puede ser un problema. Debería poder confirmar si tiene este problema utilizando algo como sp_whoisactive para examinar el bloqueo durante su reconstrucción y mirando los detalles de los bloqueos y esperas. Usar laWAIT_AT_LOW_PRIORITY
opción puede ser útil si sabe que hay un próximo período de baja utilización, y su reconstrucción puede "colarse" para este intercambio cuando la actividad cae lo suficiente como para alcanzar ese bloqueo. Tenga en cuenta que un largo plazoREBUILD
La operación también será una transacción abierta de larga duración. Las transacciones abiertas de larga duración pueden tener sus propios problemas, relacionados con el uso / reutilización del registro de transacciones. Si está utilizando duplicación o grupos de disponibilidad, también hay consideraciones para rehacer el registro de transacciones en la réplica secundaria.fuente
REORGANIZE
. Del BOL : "Reorganizar también compacta las páginas de índice". Bueno, siempre que el FILLFACTOR actual del índice permita la densidad que buscas.aviso
Después de este comentario:
... veo cómo este enfoque no funcionará.
Dejaré esta respuesta como un ejemplo de lo que no se debe hacer.
Si tiene más de 200 GB libres en su Azure DB, puede ser astuto con la "reconstrucción", copiando sus datos en una tabla totalmente nueva y ordenándolos allí.
Tratar:
LiveTable
en un vacíoNewTable
LiveTable
en elNewTable
LiveTable
aOldTable
NewTable
aLiveTable
Obviamente, use el nombre de su tabla en lugar de
LiveTable
.fuente
Idealmente, si un índice está bien diseñado, no deberíamos tener que jugar con el mecanismo de bloqueo.
Me parece que necesitará aceptar el bloqueo para desfragmentar el índice agrupado. Si hay una buena posibilidad de que esto vuelva a suceder, considere rediseñar el índice agrupado (debe ser estrecho, único, estático y en constante aumento).
No estoy seguro de qué versión de SQL Server está utilizando, pero podría intentar lo siguiente en 2012:
SET DEADLOCK_PRIORITY LOW
- Esto le dice al motor que la reconstrucción del índice debe ser la víctima del punto muerto cuando / si ocurre uno.MaxDOP = 1
- El valor MaxDOP limita el número total de CPU lógicas utilizadas en paralelo para crear el índice (2005 en adelante, solo edición Enterprise).También puede cambiar la configuración de bloqueos de página / fila, pero no lo haría sin probar. Podría empeorar el bloqueo, especialmente si es un índice mal diseñado.
A partir de 2014, existe la siguiente opción que básicamente le dice al motor que permita que continúen otras sesiones y que la operación de índice en línea espere:
fuente
¡He utilizado el mismo enfoque que Oreo descrito anteriormente con gran éxito! Lo único que falta es que necesita ejecutar un script de actualización después de copiar los datos y realizar el último cambio de nombre.
La actualización se verá así:
Si la clave es una columna de identidad, debe utilizar un enfoque ligeramente diferente.
fuente
Intente utilizar el fragmentación para distribuir los datos de su base de datos geográficamente. Entonces podrá identificar diferentes ventanas de mantenimiento para cada ubicación geográfica, y el tiempo para realizar el mantenimiento será más corto. Esto también mejorará el rendimiento. Puedes obtener más información sobre este artículo. No espere a que la base de datos se agrande.
Con grandes bases de datos y usuarios conectados las 24 horas del día, los 7 días de la semana, debe utilizar la reorganización del índice y actualizar solo las estadísticas que deben actualizarse (sp_updatestats) para minimizar el tiempo necesario para el mantenimiento y el impacto para los usuarios.
Espero que esto ayude.
fuente