![]() |
Удаление несуществующих записей Mysql
Всем доброе время суток!
Ситуация следующая: table1 --id --name --... table2 --idParent --idObject думаю понятно что это такое - реализация вложенности элементов... таблицы достаточно большие - каждая порядка 300 000 записей, но есть проблема - в table1 есть много элементов "подвисших", это значит, что таких id из первой таблице нигде нет во второй таблице в столбце idObject - значит, что на этот элемент никто не ссылается - умерший... Внимание вопрос - как сделать так, чтобы удалить такие записи... понятно что php использовать нельзя - очень долго. Запрос типа DELETE FROM table1 WHERE id NOT IN (SELECT idObject FROM table1) - точно не помню какой запрос делать, но выбирал все idObject и через оператор NOT IN - тоже не вариант - запрос 40 мин выполнялся, потом отвалился.. собственно буду очень благодарен всякого рода подсказам!:) Заранее спасибо!:) |
Цитата:
Не раскрыта тема количества записей в таблицах и наличия индексов по нужным полям. |
table2 - вместо table1 в конце - ошибся...т.е.:
DELETE FROM table1 WHERE id NOT IN (SELECT idObject FROM table2) в table1: id PRIMARY, INDEX, AUTOINDEX в table2, если уж про индексы, то там есть еще поле id: id PRIMARY, AUTOINDEX idParent и idObject - UNIQUE |
Код:
DELETE FROM table1 WHERE NOT EXISTS (SELECT idObject FROM table2 WHERE table2.idObject = table1.id) |
в общем насколько я понял ни один из запросов не подойдет - база просто виснет и все, решение нашлось корявым путем - и наверное по тому описанию, что было дано не очень легко на него было выйти.
Суть в том, что эти две таблицы реализуют древовидную структур, удалить нужно было элементы, которые "не в дереве" по какой-то (неважно какой) причине, собственно решение - выбрать все id дерева (посредством функции внешнего языка - используется php), а остальные удалить. По ходу на мускуле сделать это невозможно, т.к. нет поддержки рекурсивных функций/запросов, чтобы выбрать все дерево. Но тем не менее - был бы очень рад еще каким-нибудь решениям, потому что как уже и сказал - это очень корявое...:( |
Хм, ну в принципе да, двевовидные структуры для реляционных БД всегда были сложным местом, впрочем ту же самую рекурсию никто не мешает Вам реализовать на MySQLных функциях (судя по вложенному запросу в Вашем первом посте, у Вас не слишком древняя версия имеется). Так что просто нужно реализовать, вот и все.
|
хм... рекурсию-то сделал в итоге - получилось 13 000 нормальных id, потом делаю запрос на DELETE с оператором IN - и опять висит... не знаю что и делать..:(
|
Naked, ты запрос случайно не через веб-морду делаешь? Обычно такое поведение на тяжёлых запросах характерно именно для неё...
Такие вещи надо делать sql-скриптом через локальный консольный клиент мускуля (собственно, это верно и для других СУБД, того же Оракла к примеру)... |
нет, запрос делал прямо на серваке, в общем в итоге сделал как и написал - то, что DELETE долго выполнялся - нормально - в конечном счете он отработал и все стало нормально:) всем спасибо за участие. если кому надо:
шаг 1. пишем скрипт, который вытаскивает все id по дереву (либо на скуле - я не смог, либо на другом языке - писал на php, выполнялся не более 1 сек. (в дереве оказалось 7 000 записей уникальных)) шаг 2. удаляем все элементы в objects, которые не в дереве: DELETE FROM objects WHERE id NOT IN (SELECT id FROM temp_id_tree) шаг 3. удаляем все элементы из objectsLink, ссылки на которые ведут на несуществующие объекты DELETE FROM objectsLink WHERE idObject NOT IN (SELECT id FROM objects) AND idObject!=0 DELETE FROM objectsLink WHERE idParent NOT IN (SELECT id FROM objects) AND idParent!=0 нули там обрабатываются - специфика структуры базы, так !=0 можно и не писать... вот... пожалуй один из самых быстрых вариантов:) |
Часовой пояс GMT +4, время: 01:20. |
Powered by vBulletin® Version 3.8.5
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.