Mysql selecciona dónde no está en la tabla

votos
50

Tengo 2 tablas (A y B) con las mismas teclas principales. Quiero seleccionar todas las filas que están en A y no en B. Lo siguiente funciona:

select * from A where not exists (select * from B where A.pk=B.pk);

sin embargo, parece bastante malo (~ 2 segundos en solo 100k filas en A y de 3 a 10k menos en B)

¿Hay una mejor manera de ejecutar esto? Tal vez como una izquierda unirse?

select * from A left join B on A.x=B.y where B.y is null;

Según mis datos, esto parece funcionar un poco más rápido (~ 10%), pero ¿qué ocurre en general?

Publicado el 09/12/2008 a las 20:52
fuente por usuario
En otros idiomas...                            


5 respuestas

votos
50

Creo que tu última declaración es la mejor manera. También puedes probar

SELECT A.*    
from A left join B on 
    A.x = B.y
    where B.y is null
Respondida el 09/12/2008 a las 21:09
fuente por usuario

votos
35

Yo uso consultas en el formato de tu segundo ejemplo. Una unión suele ser más escalable que una subconsulta correlacionada.

Respondida el 09/12/2008 a las 21:47
fuente por usuario

votos
2

Se une son generalmente más rápido (en MySQL), pero también se debe considerar el esquema de indexación si encuentra que todavía se está moviendo lentamente. En general, cualquier configuración de campo como (usando INNODB) clave externa ya tendrá un conjunto de índices. Si está utilizando MYISAM, asegúrese de que todas las columnas en la instrucción ON se indexan, y considerar también la adición de cualquier columna en la cláusula WHERE al final del índice, para que sea un índice de cobertura. Esto permite que el motor tenga acceso a todos los datos necesarios en el índice, eliminando la necesidad de realizar una segunda ida y vuelta de nuevo a los datos originales. Tenga en cuenta que esto afectará a la velocidad de inserciones / actualizaciones / eliminaciones, pero puede aumentar significativamente la velocidad de la consulta.

Respondida el 28/09/2010 a las 22:58
fuente por usuario

votos
2

También uso uniones izquierdas con un criterio de tipo "where table2.id is null".

Ciertamente, parece ser más eficiente que la opción de consulta anidada.

Respondida el 27/05/2009 a las 15:52
fuente por usuario

votos
-2

Esto me ayudó mucho. Joinsson siempre más rápido que subconsultas a dar resultados:

SELECT tbl1.id FROM tbl1 t1
LEFT OUTER JOIN tbl2 t2 ON t1.id = t2.id 
WHERE t1.id>=100 AND t2.id IS NULL ;
Respondida el 14/12/2015 a las 07:25
fuente por usuario

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more