базы.
Для этого я пытаюсь поочередно удалять сначала самые дочерние записи, и дальше выше по иерархи
я имею следующую структуру:
Есть канал, у канала есть "беседы", у бесед есть сообщения. Связь один ко многим от каналов к беседам и от бесед к сообщениям беседы
Записей в таблицах дофига и больше (по 10-100млн), поэтому хочется делать это максимально эффективно
Ну я человек простой, надо удалить связанные записи - делаем
DELETE
FROM `conversation_messages`
INNER JOIN `conversations` ON `conversations`.`id` = `conversation_messages`.`conversation_id`
WHERE `conversations`.`channel_id` = ?
LIMIT 300
Запускаем, радуемся. Успешно удалено 725 записей.... Что? 725?!
Идем читать документацию - видим, что лимит не работает для мультитабличного удаления
Ну я человек простой, не умеешь так - завернем это в подзапрос, скормим отдельному запросу на удаление через
DELETE FROM `conversation_messages` WHERE `id` in (
SELECT `conversation_messages`.`id` as `id`
FROM `conversation_messages`
INNER JOIN `conversations` ON `conversations`.`id` = `conversation_messages`.`conversation_id`
WHERE `conversations`.`channel_id` = ?
LIMIT 300
)
С довольной физиономией берем в левую руку кружечку кофЭ, правой запускаем запрос..
Бац, - This version of MySQL doesn't yet support 'LIMIT & IN/ALL/ANY/SOME subquery
Да етить твою в качель.
Ну я человек простой, тогда мне ничего не остается, кроме как сделать вложенный джойн типа...
SELECT * FROM `conversation_messages` INNER JOIN (SELECT `conversation_messages`.`id` as `id`
FROM `conversation_messages`
INNER JOIN `conversations` ON `conversations`.`id` = `conversation_messages`.`conversation_id`
WHERE `conversations`.`channel_id` = ?
LIMIT 300) as sub
ON `sub`.`id` = `conversation_messages`.`id`
(Да, это селект). Запускаем - работает. Радуемся, тянем левую руку к кофЭ, правой рукой меняем селект на DELETE.
Запускаем - Бац! unexcepted keyword около inner join, иди думай дальше.
Ну я человек простой, иду к любимому комьюнити за помощью. Левой рукой слезы вытираю, правой сообщение набираю
В какой момент что-то пошло не так? Почему ему не нравится финальный запрос, если для селекта работает?
Я грешным делом уже думаю в коде приложения отдельно выгребать айдишники, отдельно скидывать их в удаление. По идее это х2 к количеству запросов, но в рамках бреда, при работе с репликами этот подход может оказаться даже эффективнее (но это не точно)
Он ждёт "Delete имя-таблицы from ... "
и действительно, работает, спасибо большое!
Обсуждают сегодня