¿Denormalizar para mejorar el rendimiento? Suena convincente, pero no retiene el agua.
Chris Date, quien en compañía del Dr. Ted Codd fue el defensor original del modelo de datos relacionales, se quedó sin paciencia con argumentos mal informados contra la normalización y los demolió sistemáticamente utilizando un método científico: obtuvo grandes bases de datos y probó estas afirmaciones.
Creo que lo escribió en Relational Database Writings 1988-1991, pero este libro luego se incluyó en la sexta edición de Introducción a los sistemas de bases de datos , que es el texto definitivo sobre teoría y diseño de bases de datos, en su octava edición mientras escribo y es probable que permanezca en imprenta en las próximas décadas. Chris Date era un experto en este campo cuando la mayoría de nosotros seguíamos corriendo descalzos.
Encontró que:
- Algunos de ellos son válidos para casos especiales
- Todos ellos no pagan por el uso general
- Todos ellos son significativamente peores para otros casos especiales.
Todo vuelve a mitigar el tamaño del conjunto de trabajo. Las uniones que involucran claves seleccionadas correctamente con índices configurados correctamente son baratas, no caras, porque permiten una reducción considerable del resultado antes de que las filas se materialicen.
La materialización del resultado implica lecturas de disco masivas, que son el aspecto más costoso del ejercicio por orden de magnitud. Realizar una unión, por el contrario, lógicamente requiere la recuperación de solo las claves . En la práctica, ni siquiera se obtienen los valores clave: los valores hash clave se utilizan para las comparaciones de unión, mitigar el costo de las uniones de varias columnas y reducir radicalmente el costo de las uniones que involucran comparaciones de cadenas. No solo encajará mucho más en la memoria caché, también hay mucho menos lectura de disco que hacer.
Además, un buen optimizador elegirá la condición más restrictiva y la aplicará antes de realizar una unión, aprovechando de manera muy efectiva la alta selectividad de las uniones en índices con alta cardinalidad.
Es cierto que este tipo de optimización también se puede aplicar a bases de datos desnormalizadas, pero el tipo de personas que desean desnormalizar un esquema generalmente no piensan en la cardinalidad cuando (si) establecen índices.
Es importante comprender que los escaneos de tabla (examen de cada fila en una tabla en el curso de producir una unión) son raros en la práctica. Un optimizador de consultas elegirá un escaneo de tabla solo cuando se mantenga una o más de las siguientes opciones.
- Hay menos de 200 filas en la relación (en este caso, un escaneo será más barato)
- No hay índices adecuados en las columnas de unión (si tiene sentido unirse en estas columnas, ¿por qué no están indexadas?
- Se requiere una conversión de tipos antes de que las columnas se pueden comparar (WTF ?! arreglarlo o volver a casa) VER NOTAS FIN DE EMISIÓN ADO.NET
- Uno de los argumentos de la comparación es una expresión (sin índice)
Realizar una operación es más costoso que no realizarla. Sin embargo, realizar la operación incorrecta , ser forzado a E / S de disco sin sentido y luego descartar la escoria antes de realizar la unión que realmente necesita, es mucho más costoso. Incluso cuando la operación "incorrecta" se calcula previamente y los índices se han aplicado con sensatez, sigue habiendo una penalización significativa. Renormalizar para precalcular una unión, a pesar de las anomalías de actualización que conlleva, es un compromiso con una unión particular. Si necesita una unión diferente , ese compromiso le costará mucho .
Si alguien quiere recordarme que es un mundo cambiante, creo que descubrirá que los conjuntos de datos más grandes en hardware más duro solo exageran la difusión de los hallazgos de Date.
Para todos ustedes que trabajan en sistemas de facturación o generadores de correo basura (la culpa es suya) y están indignados con la mano en el teclado para decirme que saben con certeza que la desnormalización es más rápida, lo siento, pero están viviendo en uno de los especiales casos: específicamente, el caso en el que procesa todos los datos, en orden. No es un caso general, y está justificado en su estrategia.
Usted está no justificados en falso generalizar él. Consulte el final de la sección de notas para obtener más información sobre el uso apropiado de la desnormalización en escenarios de almacenamiento de datos.
También me gustaría responder a
Las uniones son solo productos cartesianos con brillo labial
Qué carga de bollocks. Las restricciones se aplican lo antes posible, lo más restrictivo primero. Has leído la teoría, pero no la has entendido. Las uniones se tratan como "productos cartesianos a los que se aplican predicados" solo por el optimizador de consultas. Esta es una representación simbólica (una normalización, de hecho) para facilitar la descomposición simbólica para que el optimizador pueda producir todas las transformaciones equivalentes y clasificarlas por costo y selectividad para que pueda seleccionar el mejor plan de consulta.
La única forma en que obtendrá el optimizador para producir un producto cartesiano es no proporcionar un predicado: SELECT * FROM A,B
Notas
David Aldridge proporciona información adicional importante.
De hecho, hay una variedad de otras estrategias además de índices y escaneos de tablas, y un optimizador moderno les costará a todos antes de producir un plan de ejecución.
Un consejo práctico: si se puede utilizar como clave externa, indexarlo, de modo que el optimizador disponga de una estrategia de indexación.
Solía ser más inteligente que el optimizador MSSQL. Eso cambió hace dos versiones. Ahora generalmente me enseña . Es, en un sentido muy real, un sistema experto, que codifica toda la sabiduría de muchas personas muy inteligentes en un dominio lo suficientemente cerrado como para que un sistema basado en reglas sea efectivo.
"Bollocks" puede haber sido sin tacto. Me piden que sea menos arrogante y me recuerda que las matemáticas no mienten. Esto es cierto, pero no todas las implicaciones de los modelos matemáticos necesariamente deben tomarse literalmente. Las raíces cuadradas de los números negativos son muy útiles si evita cuidadosamente examinar su absurdo (juego de palabras allí) y se asegura de cancelarlos antes de intentar interpretar su ecuación.
La razón por la que respondí tan salvajemente fue que la declaración redactada dice que
Las uniones son productos cartesianos ...
Puede que esto no sea lo que se quiso decir, pero es lo que se escribió y es categóricamente falso. Un producto cartesiano es una relación. Una unión es una función. Más específicamente, una unión es una función de valor de relación. Con un predicado vacío producirá un producto cartesiano, y verificar que lo haga es una verificación de corrección para un motor de consulta de base de datos, pero nadie escribe uniones sin restricciones en la práctica porque no tienen ningún valor práctico fuera del aula.
Lo llamé porque no quiero que los lectores caigan en la antigua trampa de confundir el modelo con la cosa modelada. Un modelo es una aproximación, deliberadamente simplificada para una manipulación conveniente.
El límite para la selección de una estrategia de unión de exploración de tabla puede variar entre los motores de la base de datos. Se ve afectado por una serie de decisiones de implementación, como el factor de relleno del nodo de árbol, el tamaño del valor clave y las sutilezas del algoritmo, pero en términos generales, la indexación de alto rendimiento tiene un tiempo de ejecución de k log n + c . El término C es una sobrecarga fija compuesta principalmente por el tiempo de configuración, y la forma de la curva significa que no obtendrá una recompensa (en comparación con una búsqueda lineal) hasta que n esté en los cientos.
A veces la desnormalización es una buena idea
La desnormalización es un compromiso con una estrategia de unión particular. Como se mencionó anteriormente, esto interfiere con otras estrategias de unión. Pero si tiene cubos de espacio en disco, patrones de acceso predecibles y una tendencia a procesar gran parte o la totalidad de ellos, entonces puede ser muy útil precalcular una unión.
También puede averiguar las rutas de acceso que usa su operación y calcular previamente todas las uniones para esas rutas de acceso. Esta es la premisa detrás de los almacenes de datos, o al menos es cuando están construidos por personas que saben por qué están haciendo lo que están haciendo, y no solo por el cumplimiento de la palabra de moda.
Un almacén de datos correctamente diseñado se produce periódicamente mediante una transformación masiva fuera de un sistema de procesamiento de transacciones normalizado. Esta separación de las bases de datos de operaciones e informes tiene el efecto muy deseable de eliminar el choque entre OLTP y OLAP (procesamiento de transacciones en línea, es decir, entrada de datos, y procesamiento analítico en línea, es decir, informes).
Un punto importante aquí es que, aparte de las actualizaciones periódicas, el almacén de datos es de solo lectura . Esto hace discutible la cuestión de las anomalías de actualización.
No cometa el error de desnormalizar su base de datos OLTP (la base de datos en la que ocurre la entrada de datos). Puede ser más rápido para las ejecuciones de facturación, pero si lo hace, obtendrá anomalías de actualización. ¿Alguna vez trataste de que Reader's Digest dejara de enviarte cosas?
El espacio en disco es barato en estos días, así que déjate llevar. Pero la desnormalización es solo una parte de la historia de los almacenes de datos. Las ganancias de rendimiento mucho mayores se derivan de valores acumulados precalculados: totales mensuales, ese tipo de cosas. Es siempre trata de reducir el espacio de trabajo.
Problema de ADO.NET con desajustes de tipo
Suponga que tiene una tabla de SQL Server que contiene una columna indexada de tipo varchar, y usa AddWithValue para pasar un parámetro que restringe una consulta en esta columna. Las cadenas de C # son Unicode, por lo que el tipo de parámetro inferido será NVARCHAR, que no coincide con VARCHAR.
VARCHAR a NVARCHAR es una conversión cada vez más amplia, por lo que sucede implícitamente, pero diga adiós a la indexación y buena suerte para averiguar por qué.
"Cuenta los golpes en el disco" (Rick James)
Si todo está en caché en RAM, JOINs
son bastante baratos. Es decir, la normalización no tiene mucha penalización de rendimiento .
Si un esquema "normalizado" causa mucho JOINs
impacto en el disco, pero el esquema equivalente "desnormalizado" no tendría que afectar el disco, entonces la desnormalización gana una competencia de rendimiento.
Comentario del autor original: Los motores de bases de datos modernos son muy buenos para organizar la secuencia de acceso para minimizar las fallas de caché durante las operaciones de unión. Lo anterior, si bien es cierto, podría interpretarse erróneamente como que implica que las uniones son necesariamente problemáticamente caras en grandes datos. Esto llevaría a una mala toma de decisiones por parte de desarrolladores sin experiencia.