Mam bazę danych MySQL, w którym tabela A ma stosunek jeden do wielu dla tabeli B, i chciałbym zaznaczyć wszystkie wiersze w tabeli B, które nie mają dzieci w tabeli A. próbowałem, używającWybierz wiersz nadrzędny tylko wtedy, gdy nie ma dzieci
SELECT id FROM A WHERE NOT EXISTS (SELECT * FROM B WHERE B.id=A.id)
i
SELECT id FROM A LEFT JOIN B ON A.id=B.id WHERE B.id IS NULL
Oba te wydają się powoli. Czy istnieje szybsze zapytanie, aby osiągnąć to samo?
Jeśli jest to istotne, w mojej tabeli bazy danych A zawiera około 500 000 wierszy, a w tabeli B - od 3 do 4 milionów wierszy.
Edit: Dla rzeczywistych tabel w mojej bazy danych, daje mi wyjaśnić:
+----+--------------------+------------------+-------+---------------+---------------------------+---------+------+---------+--------------------------+
| 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 |
+----+--------------------+------------------+-------+---------------+---------------------------+---------+------+---------+--------------------------+
dla
select number from frontend_form471 where not exists (select * from SchoolData where SchoolData.`f471 Application Number`=frontend_form471.number)
i
+----+-------------+------------------+-------+---------------+---------------------------+---------+------+---------+------------------------------------------------+
| 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 |
+----+-------------+------------------+-------+---------------+---------------------------+---------+------+---------+------------------------------------------------+
dla
select distinct number from frontend_form471 left join SchoolData on frontend_form471.number=SchoolData.`f471 Application Number` where SchoolData.`f471 Application Number` is NULL
gdzie w moim przypadku frontend_form471 jest tabela A i SchoolData jest tabela B
Edit2: W tabeli B (SchoolData) w mojej bazy danych, identyfikator jest pierwszą częścią drugiej części klucza podstawowego, a więc jest zindeksowane i wciąż jest wiele wpisów w B o tym samym identyfikatorze.
'EXPLAIN SELECT id FROM A LEFT JOIN B na A.id = B.id GDZIE JEST NULL' B.id można zakładać wynik wyjaśniania zarówno dla zapytań? – Igor
Czy indeksy nie pomagają? – Londeren
Czy zaznacza się, jeśli 'COUNT (*) = 0' jest szybszy? –