2009-04-24 24 views

Respuesta

33

JOIN orden puede ser forzado por poner las tablas en el orden correcto en la cláusula FROM:

  1. MySQL tiene una cláusula especial llamada STRAIGHT_JOIN lo que hace que la materia orden.

    Esto utilizará un índice en b.id:

    SELECT a.Name, b.Status 
    FROM a 
    STRAIGHT_JOIN 
         b 
    ON  b.ID = a.StatusID 
    

    Y para ello se utiliza un índice en a.StatusID:

    SELECT a.Name, b.Status 
    FROM b 
    STRAIGHT_JOIN 
         a 
    ON  b.ID = a.StatusID 
    
    • Oracle tiene un toque especial ORDERED para hacer cumplir la orden JOIN:

    para ello se utiliza un índice en b.id o construir una tabla hash en b:

    SELECT /*+ ORDERED */ 
         * 
    FROM a 
    JOIN b 
    ON  b.ID = a.StatusID 
    

    Y para ello se utiliza un índice en a.StatusID o construir una tabla hash en a:

    SELECT /*+ ORDERED */ 
         * 
    FROM b 
    JOIN a 
    ON  b.ID = a.StatusID 
    
    • SQL Server tiene una pista llamada FORCE ORDER para hacer lo mismo:

    Esto utilizará un índice en b.id o construir una tabla hash en b:

    SELECT * 
    FROM a 
    JOIN b 
    ON  b.ID = a.StatusID 
    OPTION (FORCE ORDER) 
    

    Y para ello se utiliza un índice en a.StatusID o construir una tabla hash en a:

    SELECT * 
    FROM b 
    JOIN a 
    ON  b.ID = a.StatusID 
    OPTION (FORCE ORDER) 
    
    • PostgreSQL chicos, lo siento. Su TODO list dice:

    sugerencias del optimizador (no deseado)

    sugerencias del optimizador se utilizan para evitar problemas en el optimizador. Preferimos que los problemas sean reportados y corregidos.

En cuanto al orden en la comparación, no importa en cualquier RDBMS, que yo sepa.

Aunque personalmente siempre trato de estimar qué columna se buscará y coloco esta columna a la izquierda (para que parezca un lvalue).

Consulte this answer para obtener más información.

+2

¡Excelente respuesta! +1 –

+1

Con respecto a "Muchachos de PostgreSQL, perdón" - "Sugerencias del Optimizador" en el TODO oficial http://wiki.postgresql.org/wiki/Todo#Features_We_Do_Not_Want. –

+0

@Milen: Lo siento nuevamente :) – Quassnoi

8

No, no lo hace.

Lo que hago (por legibilidad) es su segundo ejemplo.

5

No. La base de datos debe determinar el mejor plan de ejecución basado en el criterio completo, no crearlo mirando cada elemento en secuencia. Puede confirmar esto solicitando el plan de ejecución para ambas consultas, verá que son las mismas (encontrará que incluso las consultas muy diferentes, siempre y cuando finalmente especifiquen la misma lógica, a menudo se compilan en el mismo plan de ejecución)

1

No, no hay. Al final del día, realmente solo está evaluando si a = b.

Y como la propiedad simétrica de la igualdad establece:

  • para cualquier cantidad a y b, si a = b, entonces b = a.

así que si marca (12)*=12 o , lógicamente, no hay diferencia.

Si los valores son iguales, únete, si no, no. Y si lo especifica como en su primer ejemplo o en el segundo, no hace diferencia.

1

Read this

SqlServer contiene una optimización para situaciones mucho más complejo que esto.

Si tiene varios criterios de cosas suele ser perezoso evaluado (pero tengo que hacer un poco de investigación en torno a casos extremos, si los hubiere.)

Para facilitar la lectura por lo general prefieren

SELECT Name, Status FROM a 
JOIN b 
ON a.StatusID = b.ID 

creo que tiene más sentido hacer referencia a la variable en el mismo orden en que fueron declarados, pero es realmente un gusto personal.

1

La única razón por la que no volvería a usar su segundo ejemplo:

select a.Name, b.Status 
from a 
inner join b 
    on b.ID = a.StatusID 

Su usuario es más probable que volver y decir '¿Puedo ver todo de incluso si no tienen registros de estado de la a.name? ' en lugar de "¿Puedo ver todos los estados bs, incluso si no tienen un registro de nombre?", así que para planificar este ejemplo, usaría On a.StatusID = b.ID en anticipación de una unión externa IZQUIERDA. Esto supone que podría tener el registro de la tabla 'a' sin 'b'.

Corrección: No cambiará el resultado.

Probablemente este sea un punto discutible ya que los usuarios nunca quieren cambiar sus requisitos.

+1

El orden no importa en una combinación IZQUIERDA o DERECHA tampoco, por lo que realmente no hace una diferencia en este caso que puedo ver Todavía puedes cambiar la cláusula para que sea IZQUIERDA ÚNICA, incluso si la cláusula ON es "b.ID = a.StatusID" –

+1

@Tom - Me alegra que hayas indicado esto. Casi tuve un ataque de pánico. –

0

no, no importa. pero aquí es un ejemplo para ayudar a hacer sus consultas más legible (al menos para mí)

select a.*, b.* 
from tableA a 
    inner join tableB b 
      on a.name=b.name 
       and a.type=b.type 

cada referencia de tabla está en una línea separada, y cada unión criterios es en una línea separada. la tabulación ayuda a mantener lo que pertenece a lo que es recto.

Otra cosa que me gustaría hacer es hacer que mis criterios en mis declaraciones en línea fluyan en el mismo orden que la tabla. entonces, si a es primero y luego b, a estará en el lado izquierdo y b a la derecha.

1

Como muchos han dicho: el orden no hace una diferencia en el resultado o el rendimiento.

Lo que quiero señalar es que LINQ to SQL solo permite el primer caso!

Por ejemplo, el ejemplo siguiente funciona bien, ...

var result = from a in db.a 
      join b in db.b on a.StatusID equals b.ID 
      select new { Name = a.Name, Status = b.Status } 

...Si bien esto arrojará errores en Visual Studio:

var result = from a in db.a 
      join b in db.b on b.ID equals a.StatusID 
      select new { Name = a.Name, Status = b.Status } 

que arroja estos errores de compilación:

  • CS1937: El 'nombre' nombre no está en el ámbito en el lado izquierdo de la ' es igual a '. Considere intercambiar las expresiones en cualquier lado de 'iguales'.
  • CS1938: El nombre 'nombre' no está en el alcance en el lado derecho de 'igual'. Considere intercambiar las expresiones en cualquier lado de 'iguales'.

Aunque no es relevante en la codificación SQL estándar, este podría ser un punto a considerar, al acostumbrarse a cualquiera de esos.

Cuestiones relacionadas