Pregunta ¿Por qué las uniones son malas cuando se considera la escalabilidad?


¿Por qué las uniones son malas o "lentas"? Sé que escuché esto más de una vez. Encontré esta cita

El problema es que las uniones son relativamente   lento, especialmente sobre datos muy grandes   conjuntos, y si son lentos su   el sitio web es lento Toma mucho tiempo   para obtener todos esos pedazos de   información de disco y ponerlos a todos   juntos de nuevo.

fuente

Siempre pensé que eran rápidos especialmente cuando buscaba un PK. ¿Por qué son 'lentos'?


76
2018-04-12 17:02


origen


Respuestas:


Unirse a dos fuentes de datos independientes es relativamente lento, al menos en comparación con no unirse a ellos. Pero recuerde que la alternativa es no tener más datos separados en absoluto; tienes que poner los dos puntos de datos dispares en el mismo registro. No puedes combinar dos datos diferentes sin que haya una consecuencia en alguna parte, así que asegúrate de entender la compensación.

La buena noticia es que las bases de datos relacionales modernas son bueno en las uniones. En realidad, no debería pensar en uniones tan lentas con una buena base de datos. La base de datos proporciona una serie de maneras de tomar uniones crudas y hacerlas mucho Más rápido:

  • Únase a una clave sustituta (columna autonoma / identidad) en lugar de a una clave natural. Esto significa comparaciones más pequeñas (y por lo tanto más rápidas) durante la operación de unión
  • Índices
  • Vistas materializadas / indexadas (piense en esto como una unión precalculada o manejado des-normalización)
  • Columna calculada Puede usar esto para comprimir o precomprar las columnas clave de una combinación, de modo que lo que sería una comparación complicada para una combinación ahora es mucho más pequeño y potencialmente preindexado.
  • Particiones de tabla (ayuda con grandes conjuntos de datos al distribuir la carga en varios discos o al limitar lo que podría haber sido un escaneo de tabla a un escaneo de partición)
  • OLAP (calcula previamente los resultados de ciertos tipos de consultas / uniones. No es del todo cierto, pero puede pensar en esto como genérico desnormalización)

Yo iría tan lejos como para decir que la razón principal por la que existen las bases de datos relacionales es para permitirle hacer uniones de manera eficiente*. Ciertamente, no es solo almacenar datos estructurados (podría hacerlo con construcciones de archivos planos como csv o xml). Algunas de las opciones que enumeré incluso le permitirán construir completamente su unión por adelantado, por lo que los resultados ya están hechos antes de emitir la consulta, como si hubiera desnormalizado los datos (a sabiendas a costa de operaciones de escritura más lentas).

Si tiene una unión lenta, probablemente no esté utilizando su base de datos correctamente. 

La des-normalización debe hacerse solo después de que estas otras técnicas hayan fallado. Y la única forma en que realmente se puede juzgar el "fracaso" es establecer metas de rendimiento significativas y medirlas. Si no ha medido, es demasiado pronto para siquiera pensar en la desnormalización.

* Es decir, existen como entidades distintas de las simples colecciones de tablas. Una razón adicional para un rdbms real es el acceso concurrente seguro.


76
2018-04-12 17:23



Las uniones pueden ser más lento que evitarlos a través de la desnormalización, pero si se usan correctamente (uniéndose a columnas con índices apropiados, etc.) no son intrínsecamente lentos.

La des-normalización es una de las muchas técnicas de optimización que puede considerar si su esquema de base de datos bien diseñado presenta problemas de rendimiento.


28
2018-04-12 17:11



el artículo dice que son lentos en comparación con la ausencia de combinaciones. esto se puede lograr con la desnormalización. entonces hay una compensación entre la velocidad y la normalización. no te olvides de la optimización prematura también :)


12
2018-04-12 17:08



En primer lugar, la razón de ser de una base de datos relacional (razón de ser) es poder modelar las relaciones entre las entidades. Las uniones son simplemente los mecanismos por los que atravesamos esas relaciones. Ciertamente tienen un costo nominal, pero sin uniones, realmente no hay razón para tener una base de datos relacional.

En el mundo académico aprendemos cosas como las diversas formas normales (1º, 2º, 3º, Boyce-Codd, etc.), y aprendemos sobre diferentes tipos de claves (primaria, extranjera, alternativa, única, etc.) y cómo estas cosas encajan juntas para diseñar una base de datos. Y aprendemos los rudimentos de SQL así como también manipulamos tanto la estructura como los datos (DDL y DML).

En el mundo corporativo, muchos de los constructos académicos resultan ser sustancialmente menos viables de lo que nos habían hecho creer. Un ejemplo perfecto es la noción de una clave principal. Académicamente es ese atributo (o colección de atributos) que identifica de manera única una fila en la tabla. Entonces, en muchos dominios problemáticos, la clave primaria académica apropiada es un compuesto de 3 o 4 atributos. Sin embargo, casi todos en el mundo corporativo moderno usan un entero secuencial autogenerado como la clave principal de una tabla. ¿Por qué? Dos razones. La primera es porque hace que el modelo sea mucho más limpio cuando estás migrando FK por todo el lugar. La segunda, y más pertinente a esta pregunta, es que la recuperación de datos a través de combinaciones es más rápida y más eficiente en un solo entero que en 4 columnas varchar (como ya se mencionó por algunas personas).

Vamos a cavar un poco más profundo ahora en dos subtipos específicos de bases de datos del mundo real. El primer tipo es una base de datos transaccional. Esta es la base de muchas aplicaciones de comercio electrónico o administración de contenido que manejan sitios modernos. Con un DB de transacciones, se está optimizando fuertemente hacia "rendimiento de transacciones". La mayoría de las aplicaciones de comercio o contenido tienen que equilibrar el rendimiento de las consultas (de ciertas tablas) con el rendimiento de las inserciones (en otras tablas), aunque cada aplicación tendrá sus propios problemas específicos de negocios para resolver.

El segundo tipo de base de datos del mundo real es una base de datos de informes. Estos se utilizan casi exclusivamente para agregar datos comerciales y generar informes comerciales significativos. Por lo general, tienen una forma diferente a las bases de datos de transacciones donde se generan los datos y están altamente optimizados para la velocidad de carga de datos en masa (ETL) y el rendimiento de consultas con conjuntos de datos grandes o complejos.

En cada caso, el desarrollador o DBA necesita equilibrar cuidadosamente tanto la funcionalidad como las curvas de rendimiento, y hay muchos trucos para mejorar el rendimiento en ambos lados de la ecuación. En Oracle puede hacer lo que se denomina un "plan de explicación" para que pueda ver específicamente cómo se analiza y se ejecuta una consulta. Está buscando maximizar el uso correcto de los índices por parte de la DB. Un desagradable realmente desagradable es poner una función en la cláusula where de una consulta. Cada vez que hace eso, garantiza que Oracle no usará ningún índice en esa columna en particular y es probable que vea un escaneo de tabla completo o parcial en el plan de explicación. Es solo un ejemplo específico de cómo se puede escribir una consulta que termina siendo lenta y no tiene nada que ver con las uniones.

Y aunque estamos hablando de escaneos de tabla, obviamente impactan la velocidad de consulta proporcionalmente al tamaño de la tabla. Una exploración de tabla completa de 100 filas ni siquiera se nota. Ejecute la misma consulta en una tabla con 100 millones de filas, y deberá regresar la próxima semana para la devolución.

Hablemos de normalización por un minuto. Este es otro tema académico en gran medida positivo que puede sobreestresarse. La mayoría de las veces, cuando hablamos de normalización, realmente nos referimos a la eliminación de datos duplicados poniéndolo en su propia tabla y migrando un FK. La gente generalmente omite toda la dependencia descrita por 2NF y 3NF. Y, sin embargo, en un caso extremo, sin duda es posible tener una base de datos BCNF perfecta que es enorme y una bestia completa para escribir código porque está tan normalizado.

Entonces, ¿dónde equilibramos? No hay una mejor respuesta única. Todas las mejores respuestas tienden a ser un compromiso entre la facilidad de mantenimiento de la estructura, la facilidad de mantenimiento de los datos y la facilidad de creación / mantenimiento del código. En general, mientras menos duplicación de datos, mejor.

Entonces, ¿por qué las uniones a veces son lentas? A veces es un mal diseño relacional. A veces es una indexación ineficaz. A veces es un problema de volumen de datos. A veces es una consulta horriblemente escrita.

Perdón por una respuesta tan larga, pero me sentí obligada a proporcionar un contexto más sustancioso en torno a mis comentarios en lugar de limitarme a una respuesta de 4 balas.


10
2018-04-13 01:00



Las personas con bases de datos de tamaño terrabyte aún usan combinaciones, si pueden hacer que funcionen en función del rendimiento, entonces tú también puedes.

Hay muchas razones para no denominar. En primer lugar, la velocidad de las consultas de selección no es la única o principal preocupación con las bases de datos. La integridad de los datos es la primera preocupación. Si se desnormaliza, debe implementar técnicas para mantener los datos desnormalizados a medida que cambian los datos principales. Supongamos que lleva a almacenar el nombre del cliente en todas las tablas en lugar de unirse a la tabla del cliente en el Id_Cliente. Ahora, cuando cambie el nombre del cliente (100% de probabilidad de que algunos de los nombres de los clientes cambien con el tiempo), ahora necesita actualizar todos los registros secundarios para reflejar ese cambio. Si hace esto, tendrá una actualización en cascada y tendrá un millón de registros secundarios, ¿qué tan rápido cree que va a ser eso y cuántos usuarios van a sufrir problemas de bloqueo y retrasos en su trabajo mientras ocurre? Además, la mayoría de las personas que se desnormalizan porque "las uniones son lentas" no conocen lo suficiente sobre las bases de datos como para asegurarse de que su integridad de datos esté protegida y, a menudo, terminan con bases de datos inutilizables porque la integridad es tan mala.

La desnormalización es un proceso complejo que requiere una comprensión profunda del rendimiento y la integridad de la base de datos si se debe hacer correctamente. No intente desnormalizar a menos que tenga dicha experiencia en el personal.

Las uniones son bastante rápidas si haces varias cosas. Primero use una clave suggorgate, una combinación int es casi la combinación más rápida. Segundo siempre indexe la clave foránea. Use tablas derivadas o condiciones de unión para crear un conjunto de datos más pequeño para filtrar. Si tiene una base de datos grande y muy compleja, contrate a una persona profesional de base de datos con experiencia en la partición y administración de enormes bases de datos. Hay muchas técnicas para mejorar el rendimiento sin deshacerse de las uniones.

Si solo necesita capacidad de consulta, entonces sí puede diseñar un datawarehouse que puede desnormalizarse y rellenarse a través de una herramienta ETL (optimizada para la velocidad) y no la entrada de datos del usuario.


9
2018-04-12 17:44



Las uniones son lentas si

  • los datos están incorrectamente indexados
  • resultados pobremente filtrados
  • unirse a la consulta mal escrita
  • conjuntos de datos muy grandes y complejos

Por lo tanto, es cierto que cuanto más grandes sean sus datos, mayor será el procesamiento que necesitará para una consulta, pero revisar y trabajar en las tres primeras opciones de lo anterior a menudo arrojará excelentes resultados.

Tu fuente da desnormalización como una opción. Esto está bien solo mientras hayas agotado mejores alternativas.


8
2018-04-12 17:13



Las uniones pueden ser lentas si se deben escanear grandes porciones de registros de cada lado.

Me gusta esto:

SELECT  SUM(transaction)
FROM    customers
JOIN    accounts
ON      account_customer = customer_id

Incluso si se define un índice en account_customer, todos los registros de este último aún deben ser escaneados.

Para la lista de consultas esto, los optimizadores decentes probablemente ni siquiera considerarán la ruta de acceso del índice, haciendo un HASH JOIN o una MERGE JOIN en lugar.

Tenga en cuenta que para una consulta como esta:

SELECT  SUM(transaction)
FROM    customers
JOIN    accounts
ON      account_customer = customer_id
WHERE   customer_last_name = 'Stellphlug'

la unión probablemente sea rápida: primero, un índice en customer_last_name se utilizará para filtrar todos los Stellphlug (que, por supuesto, no son muy numerosos), y luego un análisis de índice en account_customer se emitirá para cada Stellphlug para encontrar sus transacciones.

A pesar de que estos pueden ser miles de millones de registros en accounts y customers, solo algunos realmente necesitarán ser escaneados.


7
2018-04-12 17:07