Pregunta Restricción de una ÚLTIMA IZQUIERDA


Tengo una tabla, llamémosla "a" que se usa en una combinación de la izquierda en una vista que involucra muchas tablas. Sin embargo, solo quiero devolver filas de "a" si también se unen con otra tabla "b". Así se ve el código existente

SELECT ....
FROM main ...
...
LEFT JOIN a ON (main.col2 = a.col2)

pero está devolviendo demasiadas filas, específicamente aquellas donde a no tiene una coincidencia en b. Lo intenté

SELECT ...
FROM main ...
...
LEFT JOIN (
   SELECT a.col1, a.col2
   FROM a
   JOIN b ON (a.col3 = b.col3)) ON (a.col2 = main.col2)

lo que me da los resultados correctos, pero desafortunadamente, "EXPLICAR PLAN" dice que hacerlo de esta manera termina forzando un escaneo completo de la tabla de a y b, lo que hace que las cosas sean bastante lentas. Uno de mis compañeros de trabajo sugirió otra JUNTA IZQUIERDA en b, pero eso no funciona porque me da la fila b cuando está presente, pero no deja de devolver las filas de a que no tienen una coincidencia en b.

¿Hay alguna manera de poner la condición main.col2 en el sub-SELECT, que eliminaría los escaneos de la tabla completa? ¿O alguna otra forma de hacer lo que quiero?


5
2018-04-16 20:40


origen


Respuestas:


SELECT ...
FROM ....
LEFT JOIN ( a INNER JOIN b ON .... ) ON ....

6
2018-04-16 20:41



  1. agregue un donde (main.col2 = a.col2)

  2. solo haz una unión en lugar de una combinación de la izquierda.


3
2018-04-16 20:42



¿Qué ocurre si creas una vista que te permite unir "a" con "b" y luego haces las combinaciones de la izquierda con esa vista?


0
2018-04-16 20:42



    Select ... 
    From Main 
     Left Join a on main.col2 = a.col2
    where a.col3 in (select b.col3 from b) or a.col3 is null

Es posible que también deba realizar una indexación en a.col3 y b.col3


0
2018-04-16 20:53



Primero defina su consulta entre la tabla "a" y "b" para asegurarse de que está devolviendo las filas que desea:

Select
   a.field1,
   a.field2,
   b.field3
from
   table_a a

   JOIN table_b b
      on (b.someid = a.someid)

luego póngalo como una sub consulta de su consulta principal:

select
   m.field1,
   m.field2,
   m.field3,
   a.field1 as a_field1,
   b.field1 as b_field1
from
   Table_main m

   LEFT OUTER JOIN
      (
      Select
         a.field1,
         a.field2,
         b.field3
      from
         table_a a

         JOIN table_b b
            on (b.someid = a.someid)
      ) sq
   on (sq.field1 = m.field1)

Deberias hacer eso.

Ahh, se perdió la nota del problema de rendimiento: lo que normalmente hago es colocar la consulta de la vista en un procedimiento almacenado, por lo que puedo generar las subconsultas en las tablas temporales y colocar índices en ellas. Sorprendentemente más rápido de lo que cabría esperar. :-)


0
2018-04-16 20:54