2011-04-24 10 views
10

He encontrado un hilo similar pero realmente no capta la esencia de lo que estoy tratando de preguntar, así que he creado un nuevo hilo.¿Qué tan costoso es JOINs en SQL? Y/o ¿cuál es la compensación entre el rendimiento y la normalización?

Sé que hay un equilibrio entre la normalización y el rendimiento, y me pregunto cuál es la mejor práctica para dibujar esa línea? En mi situación particular, tengo un sistema de mensajería que tiene tres tablas distintas: messages_threads (titular de mensaje global), messages_recipients (quién está involucrado) y messages_messages (los mensajes reales + marcas de tiempo).

Para devolver la vista "bandeja de entrada", tengo que unir las tablas message_threads, users table y pictures a las tablas messages_recipients para obtener la información para completar la vista (foto de perfil, nombre del remitente, Identificación del hilo) ... y todavía tengo agregar unirme a los mensajes para recuperar el texto del último mensaje para mostrar una "vista previa" del último mensaje al usuario.

Mi pregunta es: ¿Qué tan costoso es JOINS en SQL para el rendimiento? Podría, por ejemplo, almacenar el nombre del remitente (que tengo que unir de los usuarios para recuperar) bajo un campo en la tabla messages_threads llamado "sendername" - pero en términos de normalización siempre me han enseñado a evitar la redundancia de datos.

¿Dónde trazar la línea? ¿O estoy sobreestimando cómo son las combinaciones de SQL que dificultan el rendimiento?

Respuesta

20

La mejor práctica es siempre comenzar con 3NF, y luego solo considerar la desnormalización si encuentra un problema de rendimiento específico.

El rendimiento es solo uno de los problemas que tiene que tratar con las bases de datos. Al duplicar los datos, corre el riesgo de permitir que haya datos incoherentes en su base de datos, anulando uno de los principios básicos de las bases de datos relacionales, la coherencia (C en ACID) a.

Sí, las uniones tienen un costo, no hay forma de evitar eso. Sin embargo, el costo suele ser mucho menor de lo que piensas, y a menudo puede verse afectado por otros factores, como los tiempos de transmisión de la red. Al asegurarse de que las columnas relevantes estén indexadas correctamente, puede evitar muchos de esos costos.

Y, recuerde el mantra de optimización: medida, no adivine! Y mida en un entorno de producción similar. Y mantenga midiendo (y afinando) periódicamente - la optimización es solo una operación de configuración y olvido si su esquema y datos nunca cambian (muy poco probable).


a) Reversión para un rendimiento por lo general se puede hacer seguro mediante el uso de los disparadores para mantener la consistencia. Esto, por supuesto, ralentizará sus actualizaciones, pero aún puede permitir que sus elecciones se ejecuten más rápido.

+0

Gracias pax, tienes razón, debería seguir con ACID.Gracias por aclararme eso, leí un artículo sobre sitios más grandes que se desnormalizaban y empecé a cuestionar mi estructura. – Walker

+3

@Walker, denormalisation _is_ a veces es una opción viable. Solo tienes que asegurarte de que va a ayudar más que obstaculizar :-) Al igual que con la mayoría de la vida, hay compensaciones. – paxdiablo

3

No me preocuparía mucho acerca de una unión extra. En mi experiencia, la gran pérdida de rendimiento de las uniones se produce cuando se unen grandes conjuntos de datos. Presumiblemente, su vista de mensajes mostrará 20-100 filas como máximo.

Sin embargo, una cosa: si no necesita una unión a la izquierda, simplemente use una unión normal. Se necesita una cantidad sorprendentemente significativa de tiempo extra para una combinación izquierda vs una unión regular.

Si tiene mucha curiosidad, puede establecer un punto de referencia. PHPMyAdmin le dice cuánto tiempo tardó en ejecutarse una consulta; puedes verificar el tiempo con y sin la unión final. (Solo tenga en cuenta que todas las consultas de selección de phpmyadmin son limitadas, por lo que puede esperar un tiempo de ejecución más largo si está seleccionando más de 20 filas).

+0

phpMyAdmin no es una herramienta adecuada para este tipo de trabajo. Debería usar una herramienta de escritorio como EMS MySQL Manager, Navicat for MySQL o alguna otra. – kubal5003

+0

Si necesita datos de dos grandes conjuntos de datos, las UNIONES suelen ser la forma más eficiente de obtenerlo. – dkretz

+0

Tengo Sequel Pro, que funciona bastante bien para probar el rendimiento. No tenía idea de que LEFT JOIN fuera más costoso que JOIN. Sin duda, tendré que volver atrás y reemplazar muchas declaraciones LEFT JOIN en mi código. – Walker

3

No hay una respuesta simple a esa pregunta. Los costos de las uniones varían mucho según los índices disponibles, el número de registros y muchos otros factores. AFAIR en MySQL hay al menos un par de estrategias para unirse que se ordenan del mejor al peor de los casos.

En la práctica, necesita hacer el esquema de acuerdo con las reglas generales relativas a la seguridad de los datos, así que normalice su base de datos cuando sea necesario.

La desnormalización debería ocurrir solo si tiene un problema de rendimiento real y no hay otra manera de resolverlo (por ejemplo, agregar un índice, cambiar parámetros, reescribir la consulta, ...) y debe basarse en un análisis profundo de el problema.

2

Desde mi experiencia, el impacto de los segmentos adicionales JOIN en una consulta generalmente no va a hacer o deshacer la aplicación. Indexación, evitando subconsultas, y a veces evitando las declaraciones LEFT JOIN tendrá el mayor impacto.

Como menciona Sam Dufel, establezca un punto de referencia para ver si la combinación IZQUIERDA que está utilizando debe solucionarse. También puede ser útil generar un grupo de datos ficticios para ver si se amplía a medida que aumenta el número de registros en el JOIN.

1

Las uniones son una estrategia para mejorar la eficiencia de una consulta. Y a diferencia de otra respuesta, las combinaciones externas son tan eficientes como las combinaciones internas en todos los productos que he tenido la oportunidad de enviar, que incluyen MySQL (ambos motores principales), SQL Server, Sybase y Oracle.

Lo que se debe evitar son las subconsultas (principalmente subconsultas correlacionadas), que se usa comúnmente como alternativa.

1

SIEMPRE SIEMPRE prefiero la normalización. Es terrible para mí que la desnormalización TODAVÍA reciba este tipo de atención.

NORMALIZAR - eso es lo que los motores de la base de datos están sintonizados.

+0

Gracias Randy, la única razón por la que lo cuestioné es para leer sobre la desnormalización de Twitter. – Walker

+1

sí, y probablemente haya reaccionado de forma exagerada. pero esperas que ni siquiera lo consideres hasta que demuestres que tienes algún problema con tu sistema correctamente normalizado. – Randy

1

No es posible, ni útil, responder una pregunta acerca de cuán costosas son las uniones.

Unir es solo un comando en la consulta SQL, lo que hace la base de datos con esa combinación es algo completamente diferente. Lo que es costoso en una consulta es cosas como escaneos de tabla, donde la base de datos tiene que leer una tabla completa para localizar algunos datos. Una consulta con diez uniones en tablas donde hay índices útiles puede ser mucho más rápido que una consulta en una sola tabla sin ningún índice útil.

Tres o cuatro uniones en una consulta no son razón alguna para desnormalizar las tablas para intentar mejorar el rendimiento. Como comparación; para nuestro sitio web estamos usando una tabla desnormalizada para leer, porque necesitaríamos alrededor de 40 uniones para reunir los datos que necesitamos.

Cuestiones relacionadas