2010-07-15 12 views
6

consulta:consulta MySQL con combinación izquierda es demasiado lento

select `r`.`id` as `id` 
    from `tbl_rls` as `r` 
left join `tblc_comment_manager` as `cm` on `cm`.`rlsc_id` != `r`.`id` 

Ambas tablas tienen 8k registros, pero ¿por qué es muy lenta, tomando 2-3 minutos y más veces?

OMG, esta consulta hace que el servidor mysql caiga. Se pondrá en contacto contigo en un segundo pueblos :(

Todos los pueblos los que sugirieron la indexación de las columnas son los correctos. Yeh la consulta que escribí fue tonto y el coche. Gracias corregirme.

+1

¿Hay índices? Si es así, ¿en qué columnas? – middus

+1

Ambas columnas 'id' deben tener índices – JohnB

Respuesta

15

Ten en cuenta también la indexación de sus tablas. Estamos ejecutando múltiples combinaciones a la izquierda en una tabla de registro de 1 millón o más que no toma más de un segundo o dos para devolver los resultados.

+0

Santo maldito fue este el culpable. Pasé de 10 minutos a 0.9 ms. ¿Alguna recomendación sobre una herramienta de análisis MySQL que pueda decirle qué índices debe tener en su base de datos? –

13

lo que realmente necesita el != o es destinado a ser =?

select `r`.`id` as `id` from `tbl_rls` as `r` 
    left join `tblc_comment_manager` as `cm` 
on `cm`.`rlsc_id`!=`r`.`id 

Esto seleccionará casi el producto cartesiano de las 2 tablas. (supongo que alrededor de 60 millones de filas)

Editar: "! =" Desde el comentario

sí lo es para que coincida tbl_rls.id los que no están en tblc_comment_manager

creo que esto es lo que necesita si desea utilizar el outer join enfoque.

select DISTINCT `r`.`id` as `id` from `tbl_rls` as `r` 
    left join `tblc_comment_manager` as `cm` 
on `cm`.`rlsc_id`=`r`.`id 
WHERE `cm`.`rlsc_id` IS NULL 

Aunque mi preferencia es por lo general

select `r`.`id` as `id` 
from `tbl_rls` 
as `r` 
WHERE NOT EXISTS(
      SELECT * FROM `tblc_comment_manager` as `cm` 
      WHERE `cm`.`rlsc_id`=`r`.`id) 
+0

sí, es "! =" Para que coincida con 'tbl_rls'. Id' esas no están en' tblc_comment_manager' – Arshdeep

+0

+1 para solucionar la consulta de la mina – Arshdeep

4

¿Qué desea seleccionar?

Utilice esta consulta si desea encontrar tbl_rls registros que no se emparejan los registros de otra tabla

select `r`.`id` 
from `tbl_rls` as `r` 
left join `tblc_comment_manager` as `cm` 
    on `cm`.`rlsc_id`=`r`.`id 
where `cm`.`rlsc_id` IS NULL 
+0

+1: Me ganaste, por 25 segundos ... –

1

Parece que quiere los valores de r.id que no están en la tabla tblc_comment_manager.

Utilice un No en

seleccione r. id como id
de tbl_rls como r
donde r. id no en (seleccione distinta cm. rlsc_id de tblc_comment_manager como cm)

1

MySQL de EXPLAIN podría ayudarle a descubrir lo que está pasando.

2

Es posible que deba proporcionar más información.Pero una cosa que intentar es invertir el orden de su cláusula ON (porque es tan fácil):

ON r.id != cm.rlsc_id

Editar: y usted debe poner en su índices PK (ID) columnas.

Pero creo que this article might help you out.

Básicamente dice que NOT IN toma menos recursos que LEFT JOIN. Un comentarista en ese artículo menciona que usar NOT EXISTS es lo mejor.

Además, no estoy seguro de si es exacto o no, pero this article says that NOT IN does a full table scan, and NOT EXISTS can use an index.

+1

@JohnB Para SQL Server 'NOT IN' y 'NOT EXISTS' son más eficientes (aunque se debe tener cuidado con los NULL para el primero). Para MySQL no estoy seguro de cuál es la recomendación. –

+0

Además, otros han señalado el enfoque: 'WHERE cm.rlsc_id IS NULL' – JohnB

+0

@Martin: alguien que lea ** MySQL de alto rendimiento ** podría saber la respuesta - http://www.amazon.com/High-Performance -MySQL-Jeremy-Zawodny/dp/0596003064 – JohnB

Cuestiones relacionadas