хочу от туда забирать айдишники по 100 за раз. Что-то с ними делать, затем забирать следующие 100 и так до конца
Для этого я делаю запрос SELECT id FROM ids LIMIT 100 OFFSET x, и так далее (OFFSET инкрементится)
P.S. Я знаю что такой запрос не очень (сканит всю таблицу, а там 44 миллиона записей), я бы сделал с радостью что-то вроде SELECT idx FROM ids WHERE idx> 0 AND idx <= 100; если бы мне дали добавить доп колонку с авто инкрементом и индексом по ней. Но мне пока что не дали
Мой код делающий это, могут прервать неожиданно, и я бы хотел сохранять прогресс, чтобы начать с того места, на котором остановился. Но в таблицу при этом, постоянно записываются новые айдишники. Дают ли СУБД гарантию что новые айдишники будут в конце? При условии что я их забираю таким вот запросом (SELECT id FROM ids LIMIT 100 OFFSET x)
Пример: код выполнил запрос SELECT id FROM ids LIMIT 100 OFFSET 0, затем код прервали. В это время добавилась новая запись в таблицу, мой код запустился снова и начал с 101 записи: SELECT id FROM ids LIMIT 100 OFFSET 100.
Может ли случится такое, что база вернет новую запись в контексте запроса с OFFSET 0, а старая сьедет в 101 запись и получается когда код запустится заново, сделает запрос SELECT id FROM ids LIMIT 100 OFFSET 100 и в результате пропустит одну новую запись, и обработает еще раз старую (которую он получил при первом запуске с LIMIT 100 OFFSET 0)
На практике вроде так не происходит и можно об этом не беспокоиться. Но меня всё равно это заботит, вдруг такой гарантии нет, или это зависит от СУБД или зависит от того как СУБД хранит табличные данные. Или же всё таки реляционные базы могут дать такую гарантию 🤔
Нет, гарантий не предусмотрено. Считай, что в СУБД нет понятия "начало/конец таблицы"
нет такой гарантии, хоть оно и может так себя вести. если у тебя батч работа - то тебе нужно запоминать, что ты уже обработал, а что нет. НЕ НАДО опираться на детали реализации конкретной БД, это очень бьёт в тот момент, когда ты этого не знаешь. если бд вылить в текстовый дамп, а потом залить назад - то у тебя может резко все поменяться, хотя данные окажутся те же. в общем случае как разработчик бд, я бы сказал, что я верну результаты в порядке как на диске, просто потому что это дешевле.
> о тебе нужно запоминать, что ты уже обработал, а что нет. вот этого я и хотел избежать, перегонять к себе 44 миллиона айдишников не хотелось. Хотел просто хранить offset
создай временную таблицу, добавь в ней индекс на айди, используй limit&offset, удали временную таблицу.
имеешь в виду в той базе откуда достаю айдишники? Типо INSERT INTO _tmp_ids SELECT id FROM ids ?
оно же память мыть будет, на диск дампится, и всякие другие штуки.
холодная таблица, которую используешь один раз? она будет весить 100 мегабайт на 10М записей, использоваться одним клиентом, это ~0
плюс мне всего-лишь одна колонка нужна
Обсуждают сегодня