Этот баннер — требование Роскомнадзора для исполнения 152 ФЗ.
«На сайте осуществляется обработка файлов cookie, необходимых для работы сайта, а также для анализа использования сайта и улучшения предоставляемых сервисов с использованием метрической программы Яндекс.Метрика. Продолжая использовать сайт, вы даёте согласие с использованием данных технологий».
Политика конфиденциальности
|
|
|
Транзакция
|
|||
|---|---|---|---|
|
#18+
Можно ли заключить в одну транзакцию блок,состоящий из 500 000- 1000 000 инсертов и упдейтов? Не приведет ли это к сильному замедлению производителность или к сбою сервера? Это требуется делать для того,чтобы обеспечить целостность данных (либо полное обновление либо никак и повтор процедуры заново).Транзакция оформлена в виде: BEGIN INSERT .... UPDATE .... COMMIT. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.04.2006, 05:53 |
|
||
|
Транзакция
|
|||
|---|---|---|---|
|
#18+
А если тест устроить? Т.е. задампить большую таблицу а потом попытаться вставить все в одной транзакции? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.04.2006, 09:55 |
|
||
|
Транзакция
|
|||
|---|---|---|---|
|
#18+
posttМожно ли заключить в одну транзакцию блок,состоящий из 500 000- 1000 000 инсертов и упдейтов? Не приведет ли это к сильному замедлению производителность или к сбою сервера? Это требуется делать для того,чтобы обеспечить целостность данных (либо полное обновление либо никак и повтор процедуры заново).Транзакция оформлена в виде: BEGIN INSERT .... UPDATE .... COMMIT. Все дальнейшее мною написаное ИМХО, т.к. практического опыта написания именно такого нету, но: 1. Такое количество операций естественно будет мрачно тормозить из-за как минимум rollback сегмента. Вердикт - попробовать можно, но скорее всего все будет плохо. 2. В 8.1 появился 2-х фазный коммит, и можно себе потихоньку сбрасывать данные, а потом скопом закомитить. 3. В конце концов можно сваять небольшое приложение, для тестирования и просто посмотреть что будет :) и, если не жалко, поместить результаты на форум :) 4. Сделать 2-х файзный коммит самому - т.е. в таблице/таблицах есть признак незавершенности транзакции, данные (эти insert & update) спокойно коммитятся выставляя признак незавершенности, а потом одним/несколькими опретарами update проходится и "докомичевать" все данные убирая признак незавершенности. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.04.2006, 10:02 |
|
||
|
Транзакция
|
|||
|---|---|---|---|
|
#18+
Andrey Daeron1. Такое количество операций естественно будет мрачно тормозить из-за как минимум rollback сегмента. Вердикт - попробовать можно, но скорее всего все будет плохо. В PostgreSQL нет rollback сегмента !!! И если никакая другая транзакция не позариться на апдейченную строчку локов (теоретически) не будет вообще (тормоза будут из-за ввода-вывода, но это лучше чем без транзакции. Практически же какие-то накладные расходы могут быть. Например, я заметил, что если нужно по какому-либо алгоритму обработать 100000 записей (5-6 апдейтами), то выгоднее разбить их на куски по ~500 записей - быстрее получается, как ни странно. Кроме того, если другая транзакция тоже захочет изменить строчку (нами изменённую), то лучше, если мы быстрее её отлочим. Но если на каждую строчку по апдейту - думаю разницы не будет - сразу 100000 в транзакции или по кускам. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.04.2006, 10:26 |
|
||
|
Транзакция
|
|||
|---|---|---|---|
|
#18+
Funny_Falcon Andrey Daeron1. Такое количество операций естественно будет мрачно тормозить из-за как минимум rollback сегмента. Вердикт - попробовать можно, но скорее всего все будет плохо. В PostgreSQL нет rollback сегмента !!! Хм, действительно нету... зато есть WAL!!! который ничуть не хуже, а во многих случаях лучше :) Funny_FalconИ если никакая другая транзакция не позариться на апдейченную строчку локов (теоретически) не будет вообще (тормоза будут из-за ввода-вывода, но это лучше чем без транзакции. Практически же какие-то накладные расходы могут быть. Например, я заметил, что если нужно по какому-либо алгоритму обработать 100000 записей (5-6 апдейтами), то выгоднее разбить их на куски по ~500 записей - быстрее получается, как ни странно. Это на сколько я понимаю - запись по страницам. Т.е. ПГ сбрасывает более целые страницы на диск. Funny_Falcon Кроме того, если другая транзакция тоже захочет изменить строчку (нами изменённую), то лучше, если мы быстрее её отлочим. Но если на каждую строчку по апдейту - думаю разницы не будет - сразу 100000 в транзакции или по кускам. Будет. Еще как будет. Каждый commit - это дофига работы, например сбросить ВСЕ изменения в этой транзакции на диск, а потом, бу-а-га-га, дождаться пока тормозной винт таки запишет это физически. И тут будет куча простоев, связанных с IO. С другой стороны - если долго не комитится, то в WAL все равно будут попадать или старые значения записей, или еще какая байдень. По 16 метров (сегмент) в минуту - наблюдал собственноочно :), и накопится оггроммная куча фигни, с которой что-то нужно делать. 2-х фазный комит может быть поможет. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.04.2006, 12:23 |
|
||
|
Транзакция
|
|||
|---|---|---|---|
|
#18+
Не пойму, чему может помочь 2PC. Это та же самая одна большая транзакция получится, только ждущая от координатора разрешения окончательного коммита. А поскольку про участие других ресурсов/серверов автор не сказал - никакой разницы с обычной транзакцией я не вижу. Andrey Daeron 4. Сделать 2-х файзный коммит самому - т.е. в таблице/таблицах есть признак незавершенности транзакции, данные (эти insert & update) спокойно коммитятся выставляя признак незавершенности, а потом одним/несколькими опретарами update проходится и "докомичевать" все данные убирая признак незавершенности. Это будет практически эквивалентно ещё одной вставке всего миллиона записей за раз, IMHO. Мне кажется лучше сделать аналогичную по структуре таблицу, вставлять в неё по 500-1000 записей, там же апдейтить - а потом в одной транзакции переносить готовые строки в большую таблицу. Так большая таблица пухнуть меньше будет, блокировки короче, но в лог больше записей. I/O можно уменьшить, если получится переписать UPDATE в INSERT big_table SELECT ... FROM small_table. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 19.04.2006, 03:26 |
|
||
|
Транзакция
|
|||
|---|---|---|---|
|
#18+
большое количество инсертов будет тормозить и не в транзакции.. при таких обьемах его разумнее заменить на COPY при этом если апдейты связаны с инсертами например: insert into log_mesages (user_id,message) values (555,'ddd'); update last_log_messages messge = 'ddd' where user_id=555; то имеет смысл сделать тригер after insert on log_mesages в котором обонвляется last_log_messages и вставлять данные в log_mesages через copy (хотя в этом конкретном случае лучше наверно сделать copy , а потом select last message from log_mesages ;update last_log_messages; ) это самый быстрый вариант который можно в постгре сделать...(ИМХО есетственно) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 19.04.2006, 10:38 |
|
||
|
Транзакция
|
|||
|---|---|---|---|
|
#18+
а оно точно надо? и что прям вся пачка 500000-1000000 строк прям друг от друга зависят что жить в базе кусками не могут? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 19.04.2006, 10:43 |
|
||
|
Транзакция
|
|||
|---|---|---|---|
|
#18+
Вчера написал маленькую тестовую прораммку - 500тыс записей вставляются за 70 секунд, и ни к какому падению ничего не приводят. Так что - если запись не шибко длинная, то фполне можно засунуть в одну транзакцию и надеятся что минут за 5 (300 секунд) все пройдет. А вообще хоелось бы аффтора послушать, а то все версии и версии... ЗЫ 2фффф. Подумал и понял, что 2pc совсем не причем, попітался вспомнить зачем я его хотел приплести - и тоже не вспомнил :( ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.04.2006, 10:18 |
|
||
|
Транзакция
|
|||
|---|---|---|---|
|
#18+
Работа с таблицами производится в Си программе с помощью библиотеки libpq. Читаются данные из файла затем из промежуточной таблицы выбираются данные и из них вычитаются данные из файла затем результат вычитания записывается в др таблицу в которой несколько миллионов записей и производится UPDATE промежуточной таблицы данными из файла. Все делается в одной транзакции (BEGIN действия COMMIT).В стандартном режиме вставляется несколько тыс записей,но при необходимости загрузить данные за больший промежуток времени бывает необходимость грузить больше млн. Вставка данных этим методом около 1 млн записей происходит около 2-3 часов. Причем процесс postmaster загружает проц на 89-98%,а сама прога на Си всего 0.1-0.8%. Нагрузку на винт не знаю как проверить,но думаю не он узкое место.Проц Celeron 1.3, памяти 512. Сколько при таком объеме памяти нужно выделить под shared buffers? Postgres 7.4, ядро Linux 2.4. Не представляю как с помощью команды INSERT 500000 записей вставляется за 5 мин. Может там COPY,а их насколько я знаю,нельзя заключить в транзакцию? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.04.2006, 19:17 |
|
||
|
Транзакция
|
|||
|---|---|---|---|
|
#18+
Время вставки зависит ещё и от длины записей, к примеру на обычном стареньком IDE диске 1млн коротких (~300 байт) записей вставляются в одной транзакции менее 3 минут. Узкое место здесь - именно диск, т.к. и WAL и сами данные пишутся на него. Если CPU загружается сильно - похоже что нужно крутить конфиг. Увеличение shared buffers если и поможет, то не сильно. Лучше увеличить число checkpoint_segments и размер work_mem (или как там он в 7 версии назывался). Про оптимизацию загрузки большого объема в документации есть немного . ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.04.2006, 03:42 |
|
||
|
Транзакция
|
|||
|---|---|---|---|
|
#18+
posttРабота с таблицами производится в Си программе с помощью библиотеки libpq. Читаются данные из файла затем из промежуточной таблицы выбираются данные и из них вычитаются данные из файла затем результат вычитания записывается в др таблицу в которой несколько миллионов записей и производится UPDATE промежуточной таблицы данными из файла. 1.раз уж ты из промежуточной таблици выбираеш данные целиком.. может имет смысл не обновлять их потом.. а обновлять у себя далее truncata ..copy на tmp_table? 2.потом.. стоит мосмотреть на perform... execute..(по апдейтам построить план а потом его екзекютить.. при большом количестве это даст существенный прирост) 3. из файла тупо обновлять временную таблицу.. те строки которые необновились втавлять одним запросом.. типа insert into big table select * from tem_table where is_change=1; update tmp_table set is_change =0; 4. индексы,reindex,vacuum обновлением таблиц. 5. по возможности заменить все insert на copy. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.04.2006, 10:45 |
|
||
|
|

start [/forum/topic.php?fid=53&msg=33681517&tid=2006453]: |
0ms |
get settings: |
6ms |
get forum list: |
10ms |
check forum access: |
2ms |
check topic access: |
2ms |
track hit: |
45ms |
get topic data: |
7ms |
get forum data: |
2ms |
get page messages: |
34ms |
get tp. blocked users: |
1ms |
| others: | 223ms |
| total: | 332ms |

| 0 / 0 |
