La escalabilidad se trata de pre-computar, distribuir o reducir el trabajo repetido a lo esencial para minimizar el uso de recursos por unidad de trabajo. Para escalar bien, no hace nada que no necesite en volumen, y las cosas que realmente hace, debe asegurarse de que se hagan de la manera más eficiente posible.
En ese contexto, por supuesto, unir dos fuentes de datos separadas es relativamente lento, al menos en comparación con no unirlas, porque es un trabajo que debe realizar en vivo en el punto donde el usuario lo solicita.
Pero recuerde que la alternativa ya no es tener dos datos separados en absoluto; tienes que poner los dos puntos de datos dispares en el mismo registro. No puede combinar dos datos diferentes sin una consecuencia en alguna parte, así que asegúrese de comprender la compensación.
La buena noticia es que las bases de datos relacionales modernas son buenas para las combinaciones. Realmente no debería pensar que las uniones son lentas con una buena base de datos bien utilizada. Hay varias formas fáciles de escalar para tomar uniones sin formato y hacerlas mucho más rápidas:
- Únase con una clave sustituta (usuario automático / columna de identidad) en lugar de 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 combinación precalculada o una desnormalización administrada )
- Columnas calculadas. Puede usar esto para hacer hash o precalcular las columnas clave de una combinación, de modo que lo que sería una comparación complicada para una combinación ahora sea mucho más pequeña y potencialmente preindexada.
- Particiones de tabla (ayuda con grandes conjuntos de datos al distribuir la carga a 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 una desnormalización genérica )
- Replicación, grupos de disponibilidad, trasvase de registros u otros mecanismos para permitir que varios servidores respondan consultas de lectura para la misma base de datos y, por lo tanto, escale la carga de trabajo entre varios servidores.
- Uso de una capa de almacenamiento en caché como Redis para evitar volver a ejecutar consultas que necesitan uniones complejas.
Me atrevería a 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 para 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 combinación con anticipación, por lo que los resultados ya están listos antes de emitir la consulta, como si hubiera desnormalizado los datos (ciertamente a costa de operaciones de escritura más lentas).
Si tiene una unión lenta, probablemente no esté usando su base de datos correctamente.
La desnormalización debe realizarse solo después de que estas otras técnicas hayan fallado. Y la única forma de juzgar verdaderamente el "fracaso" es establecer metas de desempeño significativas y medirlas en función de ellas. Si no ha medido, es demasiado pronto para pensar siquiera en la desnormalización.
* Es decir, existen como entidades distintas de las meras colecciones de tablas. Una razón adicional para un rdbms real es el acceso concurrente seguro.
Las uniones pueden ser más lentas que evitarlas mediante la desnormalización, pero si se usan correctamente (unir columnas con índices apropiados, etc.) no son inherentemente lentas .
La desnormalizació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.
fuente
el artículo dice que son lentos en comparación con la ausencia de uniones. esto se puede lograr con la desnormalización. por lo que existe una compensación entre velocidad y normalización. no te olvides de la optimización prematura también :)
fuente
En primer lugar, la razón de ser de una base de datos relacional (razón de ser) es poder modelar relaciones entre entidades. Las uniones son simplemente los mecanismos mediante los cuales 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 para diseñar una base de datos. Y aprendemos los rudimentos de SQL, además de manipular tanto la estructura como los datos (DDL y DML).
En el mundo empresarial, 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 clave primaria. Académicamente, es ese atributo (o colección de atributos) el que identifica de forma única una fila en la tabla. Entonces, en muchos dominios de problemas, la clave primaria académica adecuada es una combinación de 3 o 4 atributos. Sin embargo, casi todo el mundo en el mundo empresarial moderno utiliza un número entero secuencial generado automáticamente como clave principal de una tabla. ¿Por qué? Dos razones. La primera es porque hace que el modelo sea mucho más limpio cuando está migrando FK por todo el lugar. La segunda, y más relacionada con esta pregunta, es que la recuperación de datos a través de combinaciones es más rápida y eficiente en un solo entero que en 4 columnas varchar (como ya lo mencionaron algunas personas).
Profundicemos un poco más 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 administración de contenido o comercio electrónico que impulsan los sitios modernos. Con una base de datos de transacciones, está optimizando en gran medida hacia el "rendimiento de transacciones". La mayoría de las aplicaciones comerciales o de 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 impulsados por el negocio que 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 optimizadas para la velocidad de carga masiva de datos (ETL) y el rendimiento de consultas con conjuntos de datos grandes o complejos.
En cada caso, el desarrollador o DBA debe 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 llama un "plan de explicación" para que pueda ver específicamente cómo se analiza y ejecuta una consulta. Está buscando maximizar el uso adecuado de los índices de la base de datos. Un no-no realmente desagradable es poner una función en la cláusula where de una consulta. Siempre que haga eso, garantiza que Oracle no usará ningún índice en esa columna en particular y probablemente verá un escaneo de tabla completo o parcial en el plan de explicación. Ese es solo un ejemplo específico de cómo se podría escribir una consulta que termina siendo lenta y no tiene nada que ver con las combinaciones.
Y mientras hablamos de escaneos de tablas, obviamente impactan en la velocidad de consulta proporcionalmente al tamaño de la tabla. Un escaneo completo de la tabla de 100 filas ni siquiera se nota. Ejecute la misma consulta en una tabla con 100 millones de filas y deberá volver la semana que viene para obtener la devolución.
Hablemos de normalización por un minuto. Este es otro tema académico en gran medida positivo que puede sobrecargarse. La mayoría de las veces, cuando hablamos de normalización, realmente nos referimos a la eliminación de datos duplicados colocándolos en su propia tabla y migrando un FK. La gente suele saltarse todo el asunto de la dependencia descrito por 2NF y 3NF. Y, sin embargo, en un caso extremo, ciertamente es posible tener una base de datos BCNF perfecta que es enorme y una bestia completa contra la que escribir código porque está muy normalizada.
Entonces, ¿dónde nos equilibramos? No existe una única mejor respuesta. Todas las mejores respuestas tienden a ser un compromiso entre la facilidad de mantenimiento de la estructura, la facilidad de mantenimiento de datos y la facilidad de creación / mantenimiento de código. En general, cuanto 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í obligado a proporcionar un contexto más sustancioso en torno a mis comentarios en lugar de simplemente recitar una respuesta de cuatro balas.
fuente
Las personas con bases de datos del tamaño de un terrabyte todavía usan combinaciones, si pueden hacer que funcionen en términos de rendimiento, usted también puede hacerlo.
Hay muchas razones para no denominar. Primero, la velocidad de las consultas seleccionadas no es la única ni siquiera la principal preocupación con las bases de datos. La integridad de los datos es la primera preocupación. Si desnormaliza, entonces debe implementar técnicas para mantener los datos desnormalizados a medida que cambian los datos principales. Entonces, suponga que desea almacenar el nombre del cliente en todas las tablas en lugar de unirse a la tabla del cliente en client_Id. Ahora, cuando cambia 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 con una actualización en cascada y tiene un millón de registros secundarios, ¿qué tan rápido supone que será y cuántos usuarios sufrirán problemas de bloqueo y retrasos en su trabajo mientras sucede? Además, la mayoría de las personas que desnormalizan porque "
La desnormalización es un proceso complejo que requiere una comprensión profunda del rendimiento y la integridad de la base de datos para que se realice correctamente. No intente desnormalizar a menos que tenga dicha experiencia en el personal.
Las uniones son lo suficientemente rápidas si haces varias cosas. Primero use una clave suggorgate, una unión int es casi siempre la unión más rápida. En segundo lugar, indexe siempre la clave externa. Utilice 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 compleja, contrate a una persona profesional en bases de datos con experiencia en particiones y administración de bases de datos enormes. Hay muchas técnicas para mejorar el rendimiento sin deshacerse de las uniones.
Si solo necesita la capacidad de consulta, entonces sí, puede diseñar un almacén de datos que se pueda desnormalizar y se rellene a través de una herramienta ETL (optimizada para la velocidad), no mediante la entrada de datos del usuario.
fuente
Las uniones son lentas si
Entonces, es cierto, cuanto más grandes sean sus conjuntos de datos, más procesamiento necesitará para una consulta, pero verificar y trabajar en las primeras tres opciones de lo anterior a menudo dará excelentes resultados.
Su fuente da la desnormalización como una opción. Esto está bien siempre y cuando haya agotado las mejores alternativas.
fuente
Las uniones pueden ser lentas si es necesario escanear grandes porciones de registros de cada lado.
Me gusta esto:
Incluso si se define un índice en
account_customer
, todos los registros de este último deben escanearse.Para la lista de consultas esto, los optimizadores decentes probablemente ni siquiera considerarán la ruta de acceso al índice, haciendo una
HASH JOIN
o unaMERGE JOIN
en su lugar.Tenga en cuenta que para una consulta como esta:
lo más probable es que la unión sea rápida: primero,
customer_last_name
se utilizará un índice para filtrar todos los Stellphlug (que, por supuesto, no son muy numerosos), luegoaccount_customer
se emitirá un escaneo de índice para cada Stellphlug para encontrar sus transacciones.A pesar de que estos pueden ser miles de millones de registros en
accounts
ycustomers
, solo unos pocos necesitarán ser escaneados.fuente
accounts(account_customer)
mayoría de RDBMS, los RDBMS usarían ese índice para averiguar exactamente qué filas de lacustomers
base de datos deben escanearse.HASH JOIN
sería mucho más rápido, por lo que es lo que se usará, excepto en todas las bases de datos principalesMySQL
, excepto , que solo hará que elcustomers
líder en un bucle anidado (ya que es más pequeño en tamaño)Joins are fast.
Las uniones deben considerarse una práctica estándar con un esquema de base de datos normalizado correctamente. Las uniones le permiten unirse a grupos dispares de datos de una manera significativa. No temas la unión.La advertencia es que debe comprender la normalización, la unión y el uso adecuado de los índices.
Tenga cuidado con la optimización prematura, ya que la falla número uno de todos los proyectos de desarrollo es cumplir con la fecha límite. Una vez que haya completado el proyecto y comprenda las compensaciones, puede romper las reglas si puede justificarlo.
Es cierto que el rendimiento de la unión se degrada de forma no lineal a medida que aumenta el tamaño del conjunto de datos. Por lo tanto, no se escala tan bien como las consultas de tabla única, pero aún se escala.
También es cierto que un pájaro vuela más rápido sin alas, pero solo hacia abajo.
fuente
Las uniones requieren un procesamiento adicional ya que tienen que buscar en más archivos y más índices para "unir" los datos. Sin embargo, "conjuntos de datos muy grandes" es relativo. ¿Cuál es la definición de grande? En el caso de JOIN, creo que es una referencia a un gran conjunto de resultados, no a ese conjunto de datos general.
La mayoría de las bases de datos pueden procesar muy rápidamente una consulta que selecciona 5 registros de una tabla principal y une 5 registros de una tabla relacionada para cada registro (asumiendo que los índices correctos están en su lugar). Estas tablas pueden tener cientos de millones de registros cada una, o incluso miles de millones.
Una vez que su conjunto de resultados comience a crecer, las cosas se ralentizarán. Usando el mismo ejemplo, si la tabla principal da como resultado 100K registros, entonces habrá 500K registros "unidos" que deben ser encontrados. Simplemente extrayendo esa cantidad de datos de la base de datos con retrasos adicionales.
No evite las JOIN, solo sepa que puede necesitar optimizar / desnormalizar cuando los conjuntos de datos se vuelven "muy grandes".
fuente
También del artículo que citó:
y
y
El artículo trata sobre mega sitios como Ebay. En ese nivel de uso, probablemente tendrá que considerar algo más que la simple administración de bases de datos relacionales. Pero en el curso "normal" del negocio (aplicaciones con miles de usuarios y millones de registros), esos enfoques más costosos y propensos a errores son excesivos.
fuente
Las uniones se consideran una fuerza opuesta a la escalabilidad porque normalmente son el cuello de botella y no se pueden distribuir o conectar fácilmente en paralelo.
fuente
Las tablas correctamente diseñadas que contienen los índices adecuados y las consultas escritas correctamente no siempre son lentas. Donde alguna vez escuchaste eso:
no tiene idea de lo que están hablando !!! La mayoría de las uniones serán muy rápidas. Si tiene que unir muchas filas a la vez, puede recibir un golpe en comparación con una tabla desnormalizada, pero eso se remonta a las tablas diseñadas correctamente, sepa cuándo desnormalizar y cuándo no. en un sistema de informes pesado, divida los datos en tablas desnormalizadas para informes, o incluso cree un almacén de datos. En un sistema transaccional pesado, normalice las tablas.
fuente
La cantidad de datos temporales que se generan podría ser enorme en función de las combinaciones.
Por ejemplo, una base de datos aquí en el trabajo tenía una función de búsqueda genérica donde todos los campos eran opcionales. La rutina de búsqueda se unió a todas las mesas antes de que comenzara la búsqueda. Esto funcionó bien al principio. Pero, ahora que la tabla principal tiene más de 10 millones de filas ... no tanto. Las búsquedas ahora tardan 30 minutos o más.
Me encargaron optimizar el procedimiento almacenado de búsqueda.
Lo primero que hice fue que si se buscaba en alguno de los campos de la tabla principal, seleccioné una tabla temporal solo en esos campos. ENTONCES, me uní a todas las mesas con esa tabla temporal antes de hacer el resto de la búsqueda. Las búsquedas donde uno de los campos de la tabla principal ahora toman menos de 10 segundos.
Si no se comienza a buscar ninguno de los campos de la tabla principal, hago optimizaciones similares para otras tablas. Cuando terminé, ninguna búsqueda toma más de 30 segundos y la mayoría tiene menos de 10.
La utilización de la CPU del servidor SQL también disminuyó.
fuente
Si bien las uniones (presumiblemente debido a un diseño normalizado) obviamente pueden ser más lentas para la recuperación de datos que una lectura de una sola tabla, una base de datos desnormalizada puede ser lenta para las operaciones de creación / actualización de datos, ya que la huella de la transacción general no será mínima.
En una base de datos normalizada, una parte de los datos vivirá en un solo lugar, por lo que la huella para una actualización será la mínima posible. En una base de datos desnormalizada, es posible que la misma columna en varias filas o entre tablas deba actualizarse, lo que significa que la huella sería mayor y la posibilidad de bloqueos y puntos muertos puede aumentar.
fuente
Bueno, sí, seleccionar filas de una tabla desnormalizada (asumiendo índices decentes para su consulta) podría ser más rápido que seleccionar filas construidas a partir de unir varias tablas, particularmente si las uniones no tienen índices eficientes disponibles.
Los ejemplos citados en el artículo - Flickr y eBay - son casos excepcionales en mi opinión, por lo que tienen (y merecen) respuestas excepcionales. El autor destaca específicamente la falta de IR y el grado de duplicación de datos en el artículo.
La mayoría de las aplicaciones, de nuevo, en mi opinión, se benefician de la validación y la reducción de la duplicación que proporcionan los RDBMS.
fuente
Pueden ser lentos si se hacen de manera descuidada. Por ejemplo, si hace un 'seleccionar *' en una unión, probablemente tardará un poco en recuperar las cosas. Sin embargo, si elige cuidadosamente qué columnas devolver de cada tabla, y con los índices adecuados en su lugar, no debería haber ningún problema.
fuente