У меня есть база данных MySQL, в которой таблица A имеет отношение "один ко многим" с таблицей B, и я хотел бы выбрать все строки в таблице B, которые имеют в таблице нет детей. Я пробовал использовать
SELECT id FROM A WHERE NOT EXISTS (SELECT * FROM B WHERE B.id=A.id)
и
SELECT id FROM A LEFT JOIN B ON A.id=B.id WHERE B.id IS NULL
Оба варианта кажутся медленными. Есть ли более быстрый запрос для достижения того же?
В случае, если это уместно, в моей базе данных таблица A имеет около 500 000 строк, а таблица B - от 3 до 4 миллионов строк.
Изменить: Для реальных таблиц в моей базе данных объяснение дает мне:
+----+--------------------+------------------+-------+---------------+---------------------------+---------+------+---------+--------------------------+
| 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 |
+----+--------------------+------------------+-------+---------------+---------------------------+---------+------+---------+--------------------------+
для
select number from frontend_form471 where not exists (select * from SchoolData where SchoolData.`f471 Application Number`=frontend_form471.number)
и
+----+-------------+------------------+-------+---------------+---------------------------+---------+------+---------+------------------------------------------------+
| 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 |
+----+-------------+------------------+-------+---------------+---------------------------+---------+------+---------+------------------------------------------------+
для
select distinct number from frontend_form471 left join SchoolData on frontend_form471.number=SchoolData.`f471 Application Number` where SchoolData.`f471 Application Number` is NULL
, где в моем случае frontend_form471 - это таблица A, а SchoolData - это таблица B
Edit2: В таблице B (SchoolData) в моей базе данных идентификатор является первой частью двухчастного первичного ключа, поэтому он индексируется, и в B все еще есть несколько записей с тем же идентификатором.