|
Update chunks
|
|||
---|---|---|---|
#18+
Здравствуйте! Подскажите как реализовать апдейт "пачками". В таблице много записей и нужно проапдейтить один столбец по значению (WHERE column='some string') Подскажите, пожалуйста, конструкцию. База Postgres. ... |
|||
:
Нравится:
Не нравится:
|
|||
15.02.2022, 00:05 |
|
Update chunks
|
|||
---|---|---|---|
#18+
pyDev Здравствуйте! Подскажите как реализовать апдейт "пачками". В таблице много записей и нужно проапдейтить один столбец по значению (WHERE column='some string') Подскажите, пожалуйста, конструкцию. База Postgres. Варианты - 1)если есть цифровой primary key - то по его диапазонам обновлять where id>=0 and id<1000 и так далее Есть более быстрые но более геморойные в реализации методы на основе ctid если интересно расскажу отдельно завтра. -- Maxim Boguk лучшая поддержка PostgreSQL: dataegret.ru ... |
|||
:
Нравится:
Не нравится:
|
|||
15.02.2022, 00:32 |
|
Update chunks
|
|||
---|---|---|---|
#18+
Maxim Boguk pyDev Здравствуйте! Подскажите как реализовать апдейт "пачками". В таблице много записей и нужно проапдейтить один столбец по значению (WHERE column='some string') Подскажите, пожалуйста, конструкцию. База Postgres. если интересно -- Maxim Boguk лучшая поддержка PostgreSQL: dataegret.ru Интересно, буду благодарен ... |
|||
:
Нравится:
Не нравится:
|
|||
15.02.2022, 00:49 |
|
Update chunks
|
|||
---|---|---|---|
#18+
Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14.
... |
|||
:
Нравится:
Не нравится:
|
|||
15.02.2022, 10:01 |
|
Update chunks
|
|||
---|---|---|---|
#18+
Guzya Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14.
Это будет полный конец света так что то большое по обьёму обновлять там на миллиард строк.. да и на 100M тоже. Не делайте так... (а именно в части WHERE column='some string' order by id limit 2000000 - оно будет вечно работать на крупных таблицах особенно по мере того как таких записей будет всё меньше оставаться). Только диапазоны ID никаких order by/limit если вы с большими таблицами работаете. -- Maxim Boguk лучшая поддержка PostgreSQL: dataegret.ru ... |
|||
:
Нравится:
Не нравится:
|
|||
15.02.2022, 11:21 |
|
Update chunks
|
|||
---|---|---|---|
#18+
Maxim Boguk Есть более быстрые но более геморойные в реализации методы на основе ctid если интересно расскажу отдельно завтра Или уже не геморойные после обновления на pg14 Код: sql 1.
где N итерировать от 0 до relpages из pg_class записи этой таблицы с интервалом K, например в 1000. ... |
|||
:
Нравится:
Не нравится:
|
|||
15.02.2022, 11:49 |
|
Update chunks
|
|||
---|---|---|---|
#18+
Melkij Maxim Boguk Есть более быстрые но более геморойные в реализации методы на основе ctid если интересно расскажу отдельно завтра Или уже не геморойные после обновления на pg14 Код: sql 1.
где N итерировать от 0 до relpages из pg_class записи этой таблицы с интервалом K, например в 1000. Ну а на старых аналогично но через Код: sql 1.
где N и К - аналогично выше... -- Maxim Boguk лучшая поддержка PostgreSQL: dataegret.ru ... |
|||
:
Нравится:
Не нравится:
|
|||
15.02.2022, 12:04 |
|
Update chunks
|
|||
---|---|---|---|
#18+
Maxim Boguk, а не будет ли апдейт по предикату where ctid >= '(N,0)' and ctid < '(N+K,0)' "топтать" одни и те-же записи? т.е. в самом грубом приближении в таблице 3 блока, апдейтим все строки в 1-ом блоке: 1-й апдейт обновил все строки в 1-м блоке, они "переехали" частично в 3-й блок, частично в 4-й. 2-й апдейт обновил строки во втором блоке и они перешли в 4-й блок. 3-й апдейт опять апдейтит строки в 3-м блоке, которые уже были обновлены на 1 шаге (к стати - если строка при апдейте не меняется - ее ctid изменится?) и тд. я так понимаю если N не ограничить значением из relpages эта "музыка будет вечной"? те перед запуском таких обновлений таблицу лучше вакуумировать? ... |
|||
:
Нравится:
Не нравится:
|
|||
15.02.2022, 14:41 |
|
Update chunks
|
|||
---|---|---|---|
#18+
А разве relpages не может быть не актуальным, т.е. не может быть сценария, когда в relpages значение меньше, чем есть на самом деле? ... |
|||
:
Нравится:
Не нравится:
|
|||
16.02.2022, 10:39 |
|
Update chunks
|
|||
---|---|---|---|
#18+
Misha111 Maxim Boguk, а не будет ли апдейт по предикату where ctid >= '(N,0)' and ctid < '(N+K,0)' "топтать" одни и те-же записи? т.е. в самом грубом приближении в таблице 3 блока, апдейтим все строки в 1-ом блоке: 1-й апдейт обновил все строки в 1-м блоке, они "переехали" частично в 3-й блок, частично в 4-й. 2-й апдейт обновил строки во втором блоке и они перешли в 4-й блок. 3-й апдейт опять апдейтит строки в 3-м блоке, которые уже были обновлены на 1 шаге (к стати - если строка при апдейте не меняется - ее ctid изменится?) и тд. я так понимаю если N не ограничить значением из relpages эта "музыка будет вечной"? те перед запуском таких обновлений таблицу лучше вакуумировать? 1)Так а добавлять WHERE column IS DISTINCT FROM 'required value' то кто будет? Это в таких миграциях как бы самооочевидно. 2)если таблица большая то пока там процесс идёт autovacuum успеет 5 раз пройти минимум и почистить свободное место в начале блоко 3)ВАЖНО - после такой миграции надо подсчитать сколько мы случайно пропустили строк и обычным update их обновить (опять же по WHERE column IS DISTINCT FROM 'required value' )... обычно там несколько строк попадают мимо обработки на нагруженных по записи таблицах при такой обработке 4)ctid при update меняется безусловно даже если ничего в строке не поменяли и даже если HOT update сработал так что музыка вечной не будет но ограничить реальным размером таблицы (pg_relation_size) в любом случае надо. Обычно просто набор миграционных update генерируют запросом и через \gexec запускают на выполнение. -- Maxim Boguk лучшая поддержка PostgreSQL: dataegret.ru ... |
|||
:
Нравится:
Не нравится:
|
|||
16.02.2022, 10:49 |
|
Update chunks
|
|||
---|---|---|---|
#18+
Guzya А разве relpages не может быть не актуальным, т.е. не может быть сценария, когда в relpages значение меньше, чем есть на самом деле? Может поэтому лучше pg_relation_size смотреть на самом деле. Но он тоже может по ходу миграции измениться. -- Maxim Boguk лучшая поддержка PostgreSQL: dataegret.ru ... |
|||
:
Нравится:
Не нравится:
|
|||
16.02.2022, 10:50 |
|
Update chunks
|
|||
---|---|---|---|
#18+
Еще такой вопрос Код: sql 1.
j - это номер записи(смещение), но ведь на странице может быть разное количество записей (зависит от длины записи), в том числе больше 255. Или этот вопрос, как и предыдущий должен "закрываться" контрольным(простым) update в конце? ... |
|||
:
Нравится:
Не нравится:
|
|||
16.02.2022, 11:04 |
|
Update chunks
|
|||
---|---|---|---|
#18+
Guzya Еще такой вопрос Код: sql 1.
j - это номер записи(смещение), но ведь на странице может быть разное количество записей (зависит от длины записи), в том числе больше 255. Или этот вопрос, как и предыдущий должен "закрываться" контрольным(простым) update в конце? "в том числе больше 255." - это каким образом? (если база конечно руками не пересоздана с другим blocksize). блок 8kb + минимальный размер записи меньше 32байт не бывает + заголовок страницы. -- Maxim Boguk лучшая поддержка PostgreSQL: dataegret.ru ... |
|||
:
Нравится:
Не нравится:
|
|||
16.02.2022, 11:33 |
|
Update chunks
|
|||
---|---|---|---|
#18+
Maxim Boguk минимальный размер записи меньше 32байт не бывает Понял, спасибо! ... |
|||
:
Нравится:
Не нравится:
|
|||
16.02.2022, 11:47 |
|
Update chunks
|
|||
---|---|---|---|
#18+
Maxim Boguk Guzya А разве relpages не может быть не актуальным, т.е. не может быть сценария, когда в relpages значение меньше, чем есть на самом деле? Может поэтому лучше pg_relation_size смотреть на самом деле. Но он тоже может по ходу миграции измениться. pg_relation_size тяжелый, я предпочитаю запустить ANALYZE перед генерацией запросов на перебор страниц и использовать relpages как константу. если relpages окажется меньше, чем надо — сделайте частичный индекс и добейте “в лоб” одним запросом то, что осталось. если relpages получится больше — будут ошибки при обращении к страницам вне диапазона. можно вырубить vacuum_truncate для таблицы на время миграции. ... |
|||
:
Нравится:
Не нравится:
|
|||
16.02.2022, 12:13 |
|
Update chunks
|
|||
---|---|---|---|
#18+
Для Oracle я делал обновление порциями через хеш от PK. Для толстых табличек где нет partitions. Что-то типа Код: sql 1. 2. 3. 4. 5.
Правда не знаю как такая практика пригодна для PG. Уплотнять надо после каждого прохода. Можно попробовать заменить ora_hash на md5 с нужными параметрами и я думаю эффект - такойже будет. ... |
|||
:
Нравится:
Не нравится:
|
|||
16.02.2022, 20:37 |
|
Update chunks
|
|||
---|---|---|---|
#18+
mayton Для Oracle я делал обновление порциями через хеш от PK. Для толстых табличек где нет partitions. Что-то типа Код: sql 1. 2. 3. 4. 5.
Правда не знаю как такая практика пригодна для PG. Уплотнять надо после каждого прохода. Можно попробовать заменить ora_hash на md5 с нужными параметрами и я думаю эффект - такойже будет. Не эффективно (но возможно), так как индекс по id не будет использоваться... и на какой то таблице в пару терабайт размером - можно будет повесится (тем более что там надо будет по 1/1000000 делать лучше всего а это seq scan ами вечность займёт). Поэтому таки или по диапазонам id или по ctid (cамое быстрое так как на физическую адресацию в блоках базы завязано и очень по IO эффективно). -- Maxim Boguk лучшая поддержка PostgreSQL: dataegret.ru ... |
|||
:
Нравится:
Не нравится:
|
|||
16.02.2022, 21:43 |
|
Update chunks
|
|||
---|---|---|---|
#18+
Да. В моем варианте будет 8 fulltable scan. На это и был расчет. Можно 4 или 2. ... |
|||
:
Нравится:
Не нравится:
|
|||
16.02.2022, 22:03 |
|
Update chunks
|
|||
---|---|---|---|
#18+
когда то обновлял такой процедурой - размер пачки передаете параметром, после каждой итерации будет коммит, чтобы не растягивать транзакцию, и не потерять прогресс в случае отмены create or replace procedure update_chunks(cnt int) as $$ DECLARE totalcnt bigint:=0; updated bigint:=0; BEGIN select into totalcnt count(*) from test where col <> 'new'; while updated < totalcnt loop update test set col = 'new' where id in (select id from test where col <> 'new' limit cnt); updated:=updated+cnt; raise info 'updated: % / % ' ,updated,totalcnt; commit; end loop; END; $$ LANGUAGE plpgsql ... |
|||
:
Нравится:
Не нравится:
|
|||
17.02.2022, 12:13 |
|
Update chunks
|
|||
---|---|---|---|
#18+
В постгресах жеж нет UNDO-сегмента. Короче мой метод не подходит. Короче вот ораклячий опыт вообще не применим в PG. Ничего не сэкономите. ... |
|||
:
Нравится:
Не нравится:
|
|||
17.02.2022, 12:30 |
|
Update chunks
|
|||
---|---|---|---|
#18+
Посмотрите ещё на loop_execute() . ... |
|||
:
Нравится:
Не нравится:
|
|||
19.02.2022, 08:10 |
|
|
start [/forum/topic.php?fid=53&msg=40134119&tid=1993651]: |
0ms |
get settings: |
11ms |
get forum list: |
12ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
23ms |
get topic data: |
11ms |
get forum data: |
3ms |
get page messages: |
59ms |
get tp. blocked users: |
2ms |
others: | 255ms |
total: | 382ms |
0 / 0 |