Tengo una base de datos MySQL en la que la tabla A tiene una relación uno a muchos con la tabla B, y me gustaría seleccionar todas las filas en la tabla B que no tienen hijos en la tabla A. he intentado usarSeleccionar la fila principal solo si no tiene hijos
SELECT id FROM A WHERE NOT EXISTS (SELECT * FROM B WHERE B.id=A.id)
y
SELECT id FROM A LEFT JOIN B ON A.id=B.id WHERE B.id IS NULL
Ambos parecen lento. ¿Hay una consulta más rápida para lograr lo mismo?
En caso de que esto sea relevante, en mi base de datos la tabla A tiene alrededor de 500,000 filas y la tabla B tiene alrededor de 3 a 4 millones de filas.
Editar: Para las tablas reales en mi base de datos, explicar me da:
+----+--------------------+------------------+-------+---------------+---------------------------+---------+------+---------+--------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+--------------------+------------------+-------+---------------+---------------------------+---------+------+---------+--------------------------+
| 1 | PRIMARY | frontend_form471 | index | NULL | frontend_form471_61a633e8 | 32 | NULL | 671927 | Using where; Using index |
| 2 | DEPENDENT SUBQUERY | SchoolData | index | PRIMARY | PRIMARY | 49 | NULL | 3121110 | Using where; Using index |
+----+--------------------+------------------+-------+---------------+---------------------------+---------+------+---------+--------------------------+
para
select number from frontend_form471 where not exists (select * from SchoolData where SchoolData.`f471 Application Number`=frontend_form471.number)
y
+----+-------------+------------------+-------+---------------+---------------------------+---------+------+---------+------------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+------------------+-------+---------------+---------------------------+---------+------+---------+------------------------------------------------+
| 1 | SIMPLE | frontend_form471 | index | NULL | frontend_form471_61a633e8 | 32 | NULL | 671927 | Using index; Using temporary |
| 1 | SIMPLE | SchoolData | index | PRIMARY | PRIMARY | 49 | NULL | 3121110 | Using where; Using index; Not exists; Distinct |
+----+-------------+------------------+-------+---------------+---------------------------+---------+------+---------+------------------------------------------------+
para
select distinct number from frontend_form471 left join SchoolData on frontend_form471.number=SchoolData.`f471 Application Number` where SchoolData.`f471 Application Number` is NULL
donde en mi caso frontend_form471 es el cuadro A y SchoolData es la tabla B
Edit2: En la tabla B (SchoolData) en mi base de datos, la identificación es la primera parte de una clave principal en dos partes, por lo que es indexado y todavía hay entradas múltiples en B con la misma identificación.
'EXPLAIN SELECT id DE UNA UNIÓN IZQUIERDA B ON A.id = B.id WHERE B.id IS NULL' ¿podría publicar el resultado de EXPLAIN para ambas consultas? – Igor
¿Los índices no ayudan? – Londeren
¿Está seleccionando si 'COUNT (*) = 0' es más rápido? –