удаление сирот в MYSQL с помощью левого соединения - PullRequest
1 голос
/ 20 июля 2011

В MYSQL у меня есть таблица parent, у которой есть 2 внешних ключа в таблице child (a_child_id и b_child_id). Я пытаюсь удалить дочерних сирот (записи в дочерней таблице, не связанные с родительской таблицей)

select c.child_id from child c left join parent w on (w.a_child_id=c.child_id or <br/>w.b_child_id=c.child_id ) where w.parent_id is null

Из-за больших размеров таблицы указанный запрос выполнялся в течение 24 часов. Я просто хочу убедиться, что запрос правильный?

Ответы [ 2 ]

1 голос
/ 20 июля 2011

Ну, запрос SELECT не собирается ничего удалять, поэтому он ошибается по этой причине.

Я бы попробовал это:

DELETE c FROM child AS c
LEFT OUTER JOIN parent AS w1 ON c.child_id = w1.a_child_id
LEFT OUTER JOIN parent AS w2 ON c.child_id = w2.b_child_id
WHERE w1.a_child_id IS NULL AND w2.b_child_id IS NULL;

Это может показаться страннымприсоединиться к родительской таблице дважды, но, вероятно, она будет лучше использовать индексы (при условии, что у вас есть индексы для a_child_id и b_child_id).

План оптимизации следует проверить с помощью EXPLAIN.Преобразуйте удаление в SELECT и получите план оптимизации:

mysql> explain select c.child_id from child c 
left outer join parent w1 on c.child_id = w1.a_child_id 
left outer join parent w2 on c.child_id = w2.b_child_id 
where w1.a_child_id is null and w2.b_child_id is null\G
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: c
         type: index
possible_keys: NULL
          key: PRIMARY
      key_len: 8
          ref: NULL
         rows: 5
        Extra: Using index
*************************** 2. row ***************************
           id: 1
  select_type: SIMPLE
        table: w1
         type: ref
possible_keys: ac
          key: ac
      key_len: 9
          ref: test.c.child_id
         rows: 1
        Extra: Using where; Using index
*************************** 3. row ***************************
           id: 1
  select_type: SIMPLE
        table: w2
         type: ref
possible_keys: bc
          key: bc
      key_len: 9
          ref: test.c.child_id
         rows: 1
        Extra: Using where; Using index

Когда он говорит «используя индекс», это означает, что он может разрешить доступ к таблице, используя только индекс,без необходимости читать строки таблицы.

Я проверил вышеупомянутое с MySQL 5.5.12, угадывая вашу структуру таблицы из вашего описания.Я создал индекс по одному столбцу для каждого из a_child_id и b_child_id.

0 голосов
/ 20 июля 2011

Разве это не будет проще?

delete from child
where a_child_id is null
and b_child_id is null;

Или вы не определили их как внешние ключи?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...