Этот баннер — требование Роскомнадзора для исполнения 152 ФЗ.
«На сайте осуществляется обработка файлов cookie, необходимых для работы сайта, а также для анализа использования сайта и улучшения предоставляемых сервисов с использованием метрической программы Яндекс.Метрика. Продолжая использовать сайт, вы даёте согласие с использованием данных технологий».
Политика конфиденциальности
|
|
|
Вставка данных во вложенные таблицы
|
|||
|---|---|---|---|
|
#18+
Подскажите пожалуйста как красивее это сделать. Классика жанра, есть две таблицы, поле в одной является автоинкрементным уникальным ключем для другой. Если нам нужно просто вставить строку в две таблицы, то значение ключа получаем при помощи curval, проблемі начинаются в том случае, если во второй таблице уже существует запись, и все что нам нужно сделать , это найти ID поля и вставить его. Если мы сначала делаем SELECT, и только потом, в случае необходимости INSERT, эта процедура сильно замедляет процесс вставки строк в таблицу. Для того, чтобы избежать лишних SELECTов я пишу так: BEGIN INSERT INTO table_1 (value) VALUES (buf.sumvalue); variableforid = currval(table_1_id_seq); EXCEPTION WHEN unique_violation THEN SELECT INTO variableforid id from table_1 WHERE value = buf.sumvalue; END; Далее инсерт в зависимую таблицу. Но вот со временем и этот select тоже начинает притормаживать выполнение функции. Существует ли более красивый способ ? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.11.2007, 15:39 |
|
||
|
Вставка данных во вложенные таблицы
|
|||
|---|---|---|---|
|
#18+
CasufiЕсли мы сначала делаем SELECT, и только потом, в случае необходимости INSERT, эта процедура сильно замедляет процесс вставки строк в таблицу."сильно замедляет"? вы уверены, что этот select намного медленнее двух insert-ов? CasufiСуществует ли более красивый способ ?обсуждали похожий вопрос: insert or update . мне в голову более красивого способа не приходит. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.11.2007, 15:53 |
|
||
|
Вставка данных во вложенные таблицы
|
|||
|---|---|---|---|
|
#18+
LeXa NalBat"сильно замедляет"? вы уверены, что этот select намного медленнее двух insert-ов? Проверил, время выполнения при пустых таблицах (выполняются чистые инсерты) в два раза больше времени выполнения если вторая таблица заполненна. А если учесть, что в процессе выполнения функции, объем данных по которым нужно сделать SELECT WHERE растет, а время выполнения INSERT остается постоянным ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.11.2007, 16:27 |
|
||
|
Вставка данных во вложенные таблицы
|
|||
|---|---|---|---|
|
#18+
Casufi LeXa NalBat"сильно замедляет"? вы уверены, что этот select намного медленнее двух insert-ов? Проверил, время выполнения при пустых таблицах (выполняются чистые инсерты) в два раза больше времени выполнения если вторая таблица заполненна. А если учесть, что в процессе выполнения функции, объем данных по которым нужно сделать SELECT WHERE растет, а время выполнения INSERT остается постоянным Опечатался, время выполнения на чистых инсертах в два раза меньше! ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.11.2007, 16:33 |
|
||
|
Вставка данных во вложенные таблицы
|
|||
|---|---|---|---|
|
#18+
CasufiПроверил, время выполнения при пустых таблицах (выполняются чистые инсерты) в два раза больше времени выполнения если вторая таблица заполненна.я тоже проверил. попытался сравнить скорости select, insert, неудачный insert. select выполняется в два раза быстрее insert-а, время неудачного insert-а получить не удалось. Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. CasufiА если учесть, что в процессе выполнения функции, объем данных по которым нужно сделать SELECT WHERE растет, а время выполнения INSERT остается постояннымпочему у вас так происходит? select и insert должны перелопачивать одинаковый объем данных по уникальному индексу. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.11.2007, 17:00 |
|
||
|
Вставка данных во вложенные таблицы
|
|||
|---|---|---|---|
|
#18+
LeXa NalBatпочему у вас так происходит? select и insert должны перелопачивать одинаковый объем данных по уникальному индексу. Я не очень давно пробую писать для Postgre, поєтому толком профилировать функции не умею, и не могу сказать почему так происходит. Подскажите, можно использовать "explain analyze" в теле функции? Нашел еще одну интересную особенность, есть функция "insert_dvizh" которая обрабатывает одну строку из буферной таблицы, скорость обработки по идее должна немного увеличиваться по мере наполнения таблицы данными, а не от количества строк в запросе. Но почемуто 10 запросов SELECT id, insert_dvizh(id) from buffer limit 1000 выполняются в 4-6 раз быстрее чем один запрос SELECT id, insert_dvizh(id) from buffer limit 10000 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.11.2007, 17:32 |
|
||
|
Вставка данных во вложенные таблицы
|
|||
|---|---|---|---|
|
#18+
Casufi Но почемуто 10 запросов SELECT id, insert_dvizh(id) from buffer limit 1000 выполняются в 4-6 раз быстрее чем один запрос SELECT id, insert_dvizh(id) from buffer limit 10000 Расходы на транзакцию во втором случае больше. Транзакция изолирует от остального мира бОльший объем данных на бОльшее время. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.11.2007, 17:40 |
|
||
|
Вставка данных во вложенные таблицы
|
|||
|---|---|---|---|
|
#18+
tadminРасходы на транзакцию во втором случае больше. Транзакция изолирует от остального мира бОльший объем данных на бОльшее время. Грубо говоря, если база будет крутиться на сервере с лостаточным количеством оперативки а не на рабочей станции, то время обработки должно постепенно сравниваться ? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.11.2007, 17:47 |
|
||
|
Вставка данных во вложенные таблицы
|
|||
|---|---|---|---|
|
#18+
CasufiПодскажите, можно использовать "explain analyze" в теле функции? Вот как можно план изнутри функции просмотреть CasufiНо почемуто 10 запросов SELECT id, insert_dvizh(id) from buffer limit 1000 выполняются в 4-6 раз быстрее чем один запрос SELECT id, insert_dvizh(id) from buffer limit 10000в обоих случаях в таблицы успешно добавляется 10 000 строк? PS: вы используете limit без order by ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.11.2007, 17:49 |
|
||
|
Вставка данных во вложенные таблицы
|
|||
|---|---|---|---|
|
#18+
tadmin Casufi Но почемуто 10 запросов SELECT id, insert_dvizh(id) from buffer limit 1000 выполняются в 4-6 раз быстрее чем один запрос SELECT id, insert_dvizh(id) from buffer limit 10000 Расходы на транзакцию во втором случае больше. Транзакция изолирует от остального мира бОльший объем данных на бОльшее время. КРоме этого, возможно ли выполнить запрос так, чтобы расчеты по каждой строке, которая возвращается в этом запросе выполнялись в отдельной транзакции ? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.11.2007, 17:59 |
|
||
|
Вставка данных во вложенные таблицы
|
|||
|---|---|---|---|
|
#18+
LeXa NalBatв обоих случаях в таблицы успешно добавляется 10 000 строк? PS: вы используете limit без order by В оригинальном запросе LIMIT используется вместе с ORDER BY Сама функция вставляет данные в 7 таблиц. Результат выполнения 1 селекта на 1000 строк и 10 на 100 абсолютно одинаковый. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.11.2007, 09:55 |
|
||
|
Вставка данных во вложенные таблицы
|
|||
|---|---|---|---|
|
#18+
пожалуй, придерусь к фразе (из альтруистических соображений), хотя и небольшой оффтопик Casufi[Результат выполнения 1 селекта на 1000 строк и 10 на 100 абсолютно одинаковый. В общем случае это неверно даже с использованием ORDER BY , так как любая завершившаяся транзакция (можду этими 10-тью вызовами select ... limit 1000 ), которая изменит таблицу buffer, может повлиять на следущий select ... limit 1000 таким образом, что целостность данных при этом будет потеряна, то есть Код: plaintext ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.11.2007, 11:32 |
|
||
|
Вставка данных во вложенные таблицы
|
|||
|---|---|---|---|
|
#18+
LeXa NalBat Вот как можно план изнутри функции просмотреть и уже в ссылке: LeXa NalBatНе получается посмотреть таким способом план запроса с параметрами. Так можно (если можно, то как?) посмотреть план запроса с параметрами? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.11.2007, 11:47 |
|
||
|
Вставка данных во вложенные таблицы
|
|||
|---|---|---|---|
|
#18+
Casufiвозможно ли выполнить запрос так, чтобы расчеты по каждой строке, которая возвращается в этом запросе выполнялись в отдельной транзакции ?наверное нельзя CasufiНо почемуто 10 запросов SELECT id, insert_dvizh(id) from buffer limit 1000 выполняются в 4-6 раз быстрее чем один запрос SELECT id, insert_dvizh(id) from buffer limit 10000в обоих случаях в таблицы успешно добавляется 10 000 строк? Gold_Так можно (если можно, то как?) посмотреть план запроса с параметрами? получилось посмотреть explain без analyze ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.11.2007, 12:24 |
|
||
|
Вставка данных во вложенные таблицы
|
|||
|---|---|---|---|
|
#18+
Casufi tadminРасходы на транзакцию во втором случае больше. Транзакция изолирует от остального мира бОльший объем данных на бОльшее время. Грубо говоря, если база будет крутиться на сервере с лостаточным количеством оперативки а не на рабочей станции, то время обработки должно постепенно сравниваться ? теоретически - да. На практике размер транзакции сложно влияет на скорость исполнения и зависит многих факторов: 1) помещается ли размер транзакции в ОЗУ? 2) помещается ли размер транзакции в кеш процессора (1-2-6 мб)? 3) нет ли плохого кода в самом постгресе, который приводит к скорости исполнения порядка O(N^2)? На обычных задачах, ограничением является п 2). Как только транзакция (изоляция индексов и таблиц) начинается вытеснятся из кеша процессора, тут же появляется зависимость хуже чем O(N) На моей практике (импорт больших объемов данных со сложными вставками во множество таблиц), есть оптимальный размер транзакции. При переходе с 7ки на 8ку на одном железе оптимальный размерм транзакции вместо 20 записей стал 50. При переходе со старого Xeon на Opteron 852 опт. размер стал 80-90. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.11.2007, 12:37 |
|
||
|
Вставка данных во вложенные таблицы
|
|||
|---|---|---|---|
|
#18+
Предлагаю в ФАК: Вопрос: Правда ли что в PostgreSQL скорость выполнения транзакции (множество операций INSERT) не зависит от размеров транзакции? Ответ (с)tadmin: На практике размер транзакции сложно влияет на скорость исполнения и зависит многих факторов: 1) помещается ли размер транзакции в ОЗУ? 2) помещается ли размер транзакции в кеш процессора (1-2-6 мб)? 3) нет ли плохого кода в самом постгресе, который приводит к скорости исполнения порядка O(N^2)? На обычных задачах, ограничением является п 2). Как только транзакция (изоляция индексов и таблиц) начинается вытеснятся из кеша процессора, тут же появляется зависимость хуже чем O(N) На моей практике (импорт больших объемов данных со сложными вставками во множество таблиц), есть оптимальный размер транзакции. При переходе с 7ки на 8ку на одном железе оптимальный размерм транзакции вместо 20 записей стал 50. При переходе со старого Xeon на Opteron 852 опт. размер стал 80-90. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.11.2007, 14:09 |
|
||
|
Вставка данных во вложенные таблицы
|
|||
|---|---|---|---|
|
#18+
нашел свои старые измерения. Импорт 15тыс записей, которые набор из 5-6 хранимых процедур plpgsql распихивает в 4-5 таблиц. Измерения проводились на машине dual Xeon 2.4, 2Gb RAM 5x 15K rpm RAID5 Импорт 15К записей, зависимость от chunksize (число записей за 1 транзакцию) 98% загрузка на 1 процессор, <40.0 IOPS, postmaster memory ~40mb В данном случае скорость лимитировалась только процессором. Накладные расходы на одну транзакцию состоят из C1 - постоянной части (не зависит от chunk size) C2 - переменной части (зависит от chunk size). В данном случае С1 сравнимо с С2 при chunksize=20 , где и виден оптимум. C2 всегда растет с увеличением chunk size. На более совершенных процессорах и/или больших размерах L2-L3 кеша минимум на графике смещается вправо. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.11.2007, 14:40 |
|
||
|
Вставка данных во вложенные таблицы
|
|||
|---|---|---|---|
|
#18+
Dan Blackпожалуй, придерусь к фразе (из альтруистических соображений), хотя и небольшой оффтопик Casufi[Результат выполнения 1 селекта на 1000 строк и 10 на 100 абсолютно одинаковый. В общем случае это неверно даже с использованием ORDER BY , так как любая завершившаяся транзакция (можду этими 10-тью вызовами select ... limit 1000 ), которая изменит таблицу buffer, может повлиять на следущий select ... limit 1000 таким образом, что целостность данных при этом будет потеряна, то есть Код: plaintext Во первых не SELECT *, а SELECT id_field, some_func(id_field) FROM table ORDER BY id_field И только от содержимого функции будет зависет совпадет результат или нет. В моем случае функция удаляет за собой строку из базы, поєтому два раза одна строка не обрабатывается ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.11.2007, 17:42 |
|
||
|
Вставка данных во вложенные таблицы
|
|||
|---|---|---|---|
|
#18+
Итак, получается, что весь запрос SELECT id_field, some_func(id_field) FROM table ORDER BY id_field выполняется в одной транзакции, поэтому производительность данной операции сильно падает. Подскажите пожалуйста, можно ли сделать так, чтобы каждая строка этого запроса выполнялась в отдельной транзакции ? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.11.2007, 14:36 |
|
||
|
|

start [/forum/topic.php?fid=53&msg=34939719&tid=2004854]: |
0ms |
get settings: |
11ms |
get forum list: |
12ms |
check forum access: |
2ms |
check topic access: |
2ms |
track hit: |
61ms |
get topic data: |
12ms |
get forum data: |
3ms |
get page messages: |
78ms |
get tp. blocked users: |
2ms |
| others: | 240ms |
| total: | 423ms |

| 0 / 0 |
