IMHO.WS

IMHO.WS (http://www.imho.ws/index.php)
-   Веб-программирование (http://www.imho.ws/forumdisplay.php?f=29)
-   -   Удаление несуществующих записей Mysql (http://www.imho.ws/showthread.php?t=139167)

Naked 10.04.2009 22:23

Удаление несуществующих записей 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 мин выполнялся, потом отвалился..
собственно буду очень благодарен всякого рода подсказам!:)

Заранее спасибо!:)

RaZEr 10.04.2009 22:33

Цитата:

Сообщение от Naked (Сообщение 1647129)
Запрос типа DELETE FROM table1 WHERE id NOT IN (SELECT idObject FROM table1)

Я тут table2 не вижу.

Не раскрыта тема количества записей в таблицах и наличия индексов по нужным полям.

Naked 10.04.2009 22:38

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

Hubbitus 12.04.2009 21:43

Код:

DELETE FROM table1 WHERE NOT EXISTS (SELECT idObject FROM table2 WHERE table2.idObject = table1.id)
не спасет отца русской демократии?

Naked 12.04.2009 23:11

в общем насколько я понял ни один из запросов не подойдет - база просто виснет и все, решение нашлось корявым путем - и наверное по тому описанию, что было дано не очень легко на него было выйти.
Суть в том, что эти две таблицы реализуют древовидную структур, удалить нужно было элементы, которые "не в дереве" по какой-то (неважно какой) причине, собственно решение - выбрать все id дерева (посредством функции внешнего языка - используется php), а остальные удалить. По ходу на мускуле сделать это невозможно, т.к. нет поддержки рекурсивных функций/запросов, чтобы выбрать все дерево.
Но тем не менее - был бы очень рад еще каким-нибудь решениям, потому что как уже и сказал - это очень корявое...:(

Hubbitus 12.04.2009 23:26

Хм, ну в принципе да, двевовидные структуры для реляционных БД всегда были сложным местом, впрочем ту же самую рекурсию никто не мешает Вам реализовать на MySQLных функциях (судя по вложенному запросу в Вашем первом посте, у Вас не слишком древняя версия имеется). Так что просто нужно реализовать, вот и все.

Naked 12.04.2009 23:34

хм... рекурсию-то сделал в итоге - получилось 13 000 нормальных id, потом делаю запрос на DELETE с оператором IN - и опять висит... не знаю что и делать..:(

Borland 13.04.2009 00:34

Naked, ты запрос случайно не через веб-морду делаешь? Обычно такое поведение на тяжёлых запросах характерно именно для неё...
Такие вещи надо делать sql-скриптом через локальный консольный клиент мускуля (собственно, это верно и для других СУБД, того же Оракла к примеру)...

Naked 13.04.2009 00:56

нет, запрос делал прямо на серваке, в общем в итоге сделал как и написал - то, что 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.