удалить записи из таблицы, используя другую таблицу? - PullRequest
1 голос
/ 17 сентября 2009

примечание: для редакторов: пожалуйста, отредактируйте название, если есть лучшее:)

мой вопрос:

У меня есть две таблицы в моей базе данных

     -----------
     | table1   |
     |----------|
     | id       |
     |text      |
     ===========


     -----------
     | table2   |
     |----------|
     | id       |
     |text      |
     ===========

table1 - 600 000 записей

table2 - это 5 000 000 записей !!:)

Каков наилучший способ удалить все записи в таблице2, которых нет в таблице1

Кстати, самый быстрый способ, потому что я не хочу ждать 4 часа, чтобы завершить процесс

у вас есть что-то лучше, чем следующий код:

<?PHP
   $sql = "select text from table2";
   $result = mysql_query($sql) or die(mysql_error());
   while($row = mysql_fetch_array($result)){
        $text = $row["text"];
        $sql2 = "select id from table1 where text = '$text'";
        $query2 = mysql_query($sql2) or die(mysql_error());
        $result2 = mysql_num_rows($query2);
        if($result2==0){
             $sql3 = "delete from table2 where text = '$text'";
             $query3 = mysql_query($sql3) or die(mysql_error());
        }
   }
?>

Спасибо

Ответы [ 5 ]

5 голосов
/ 17 сентября 2009

как насчет того, чтобы позволить RDBM справиться с этим?

например

DELETE FROM table2 WHERE text NOT IN (select distinct text from table1)

Приветствия

PS: сделайте резервную копию перед тестированием ...

3 голосов
/ 17 сентября 2009

Ваше решение делает что-то вроде 2 запросов на строку в таблице table2 - что означает пару миллионов запросов - что будет довольно медленно ^^

Используя MySQL, вы можете удалить все это только в одном запросе: инструкция DELETE может использоваться для удаления данных из нескольких таблиц.

Первым делом нужно написать инструкцию выбора, которая будет соответствовать данным, которые вы хотите удалить (это лучший способ проверить, чем попытаться удалить, не зная, действительно ли он будет работать с правильными данными) ; что-то вроде этого может сделать:

select table2.*
from table2
    left join table1 on table1.text = table2.text
where table1.id is NULL

Это должно получить все данные, которые находятся в таблице 2, но отсутствуют в таблице 1.

Как только вы убедитесь, что этот запрос получает правильные данные, вы можете преобразовать его в запрос на удаление:

delete table2
from table2
    left join table1 on table1.text = table2.text
where table1.id is NULL

Это может подойти - конечно, лучше сначала провести тестирование на тестовой базе данных, а не на рабочей!

Иначе, что-то с IN и подзапросом может подойти; немного похоже

delete
from table2
where text not in (select text from table1)

Не уверен, что будет быстрее, хотя, учитывая количество данных, которые у вас есть - все равно, в любом случае, я бы не делал предложенный вами цикл PHP, но использовал бы SQL-запрос, который может удалить все сам : избегание всех этих вызовов из PHP в БД, безусловно, ускорит процесс!

1 голос
/ 17 сентября 2009

Попробуйте это:

DELETE table2 Where id NOT IN (SELECT id from table1)

Примечание. Сделайте резервную копию перед выполнением запроса

1 голос
/ 17 сентября 2009

Почему бы не добавить новый столбец в table2, который составляет один байт, а затем просто обновить параметр, для которого байт равен true или 'Y', если эта строка находится в обеих таблицах.

Затем просто удалите строки, для которых не установлен этот один столбец.

Это кажется самым простым и быстрым, ИМО.

0 голосов
/ 17 сентября 2009

Создать table3 как table2 вставить в table3 (SELECT table2.ID, TABle2.TEXT из table1 присоединиться к table2 на ...) Drop Table2 измените table3 новое имя table2

Включает немного управления (так что это только допустимый вариант, если вы можете легко удалить / изменить таблицы), но, по крайней мере, часть DML превзойдет любой другой вариант, например ,ink.

...