Me llamaron la atención que la USING
construcción (en lugar de ON
) en la FROM
cláusula de SELECT
consultas podría introducir barreras de optimización en ciertos casos.
Me refiero a esta palabra clave:
SELECCIONAR * A partir de una ÚNETE b USANDO (a_id)
Solo en casos más complejos.
Contexto: este comentario a esta pregunta .
Lo uso mucho y nunca he notado nada hasta ahora. Estaría muy interesado en un caso de prueba que demuestre el efecto o cualquier enlace a más información. Mis esfuerzos de búsqueda quedaron vacíos.
La respuesta perfecta sería un caso de prueba para mostrar USING (a_id)
con un rendimiento inferior en comparación con la cláusula de unión alternativa ON a.a_id = b.a_id
, si eso realmente puede suceder.
postgresql
performance
optimization
join
select
Erwin Brandstetter
fuente
fuente
USING
es un poco más rápido , ya que da como resultado una columna menos en la matriz de resultados. Sus hallazgos se remontan a 2005 y 2008. Supongo que cualquier problema ya se ha solucionado. Sin embargo , puedo ver una posible limitación: las uniones conUSING
pueden tener que aplicarse en orden , ya que la columna de unión resultante es un producto conjunto. De este modo, se pueden limitar las opciones de reordenamiento de JOIN.id
como nombre de columna.Respuestas:
Erwin: Estoy de acuerdo con la idea de que USAR causar un pedido rígido podría crear muchos casos extremos en los que se descartarían planes óptimos. Recientemente ayudé a alguien que tenía algo como esto en su consulta:
En su caso, el peor de estos bloques de unión estaba causando una unión de bucle anidado a través de unas 200k filas, unas 20k veces (hacer los cálculos), y dado que las teclas no se podían empujar a los índices, era una exploración secuencial. Esto significó que la consulta general tardó aproximadamente 3 horas en ejecutarse debido a cambios en el plan en cascada. Al distribuir la combinación izquierda, las teclas se pueden presionar y la consulta se ejecuta en cuestión de segundos. Por supuesto, esto no es exactamente equivalente, es por eso que el planificador no puede tratarlos como equivalentes, por lo que se dejó descubrir ese plan como una combinación hash y luego hizo un bucle anidado, que fue dolorosamente lento.
Cada vez que fuerza rígidamente a que se unan las uniones en un cierto orden, introduce casos en los que la información clave del filtro puede no estar disponible todavía en la ejecución del plan, y entonces, ¿qué podría hacerse más adelante en una exploración rápida de índice / hash? Es posible que tenga que hacerse mucho más lento en un bucle anidado / exploración secuencial y, si bien el fragmento anterior no es inmediatamente equivalente, muestra el mismo problema.
fuente