Выбирайте родительскую строку, только если у нее нет дочерних элементов

У меня есть база данных 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 все еще есть несколько записей с тем же идентификатором.

10
задан murgatroid99 19 July 2011 в 19:34
поделиться