DELETE кажется эффективным. На деле нет. Так можно легко положить базу.Когда ты делаешь большой
DELETE одним запросом, база держит блокировки на всех затронутых строках до конца операции. Если запрос выполняется 30 секунд, блокировки висят 30 секунд. Любые другие запросы, которым нужны эти строки, встают и ждут.На нагруженных системах (много чтений и апдейтов) это разъезжается волной. Чтения начинают копиться, записи блокируются, пул соединений забивается. Такой “клининг” очень легко превращается в продовый инцидент :)
Есть еще WAL (transaction log). Массовый
DELETE генерит огромный объем логов разом, что может резко поднять disk I/O и замедлить репликацию. Реплики начинают отставать, иногда очень заметно.Фикс простой: удаляй батчами.
DELETE ... WHERE ... LIMIT 1000, потом небольшая пауза, потом повтор. По общему времени это может быть дольше, зато блокировки короткие, записи в WAL размазаны по времени, и база остается отзывчивой.Забавный факт: базы не спасут тебя от тебя самого :) Это как раз из тех вещей, которые ты усваиваешь один раз, обычно на факапах. Не спрашивай, откуда знаю :) 🎉
👉 @SQLPortal