Этот баннер — требование Роскомнадзора для исполнения 152 ФЗ.
«На сайте осуществляется обработка файлов cookie, необходимых для работы сайта, а также для анализа использования сайта и улучшения предоставляемых сервисов с использованием метрической программы Яндекс.Метрика. Продолжая использовать сайт, вы даёте согласие с использованием данных технологий».
Политика конфиденциальности
|
|
|
INSERT в большую БД
|
|||
|---|---|---|---|
|
#18+
Есть скрипт на Си,который читает файл и из него пишет в БД.При малом кол-ве записей в базе читает довольно быстро,но при кол-ве записей около 1 млн INSERTы выполняются медленно. Как можно ускорить вставку записей. Привожу запросы: sprintf(str,"SELECT bytes,dest,date_last,time_last FROM iptables_last WHERE dest='%s' and source='0.0.0.0/0'",dest); res=PQexec(conn,str); bytes_new=atof(bytes)-atof(PQgetvalue(res,0,0)); sprintf(str,"INSERT INTO iptables (bytes,prot,source,dest,date_second,time_second,date_first,time_first) \ VALUES ('%f','%s','%s','%s','%s','%s','%s','%s'); \ UPDATE iptables_last SET bytes='%s',date_last='%s',time_last='%s' \ WHERE dest='%s';",bytes_new,prot,source,dest,PQgetvalue(res,0,2),PQgetvalue(res,0,3),dat_st_,time,bytes,dat_st_,time,dest); res = PQexec(conn,str); ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.03.2006, 10:47 |
|
||
|
INSERT в большую БД
|
|||
|---|---|---|---|
|
#18+
Хотя может это нормальная ситуация,но что тогда будет с БД при числе записей в 20-30 млн. и более???Я думаю так быть не должно и что-то можно оптимизировать,если нужна более подробная информация,говорите какая. EXPLAIN ANALYZE INSERT INTO iptables_last (bytes,prot,source,dest,date_last,time_last) VALUES (0,'','1.1.1.1','1.1.1.1','2006-01-01','01:01:01'); QUERY PLAN -------------------------------------------------------------------------------------- Result (cost=0.00..0.01 rows=1 width=0) (actual time=25.859..25.861 rows=1 loops=1) Total runtime: 150.591 ms Таблица: \d iptables Table "public.iptables" Column | Type | Modifiers -------------+------------------------+------------------------------------------------------------ id_iptables | integer | not null default nextval('iptables_id_iptables_seq'::text) bytes | double precision | prot | text | source | inet | dest | inet | date_second | date | time_second | time without time zone | date_first | date | time_first | time without time zone | Indexes: "iptables_pkey" primary key, btree (id_iptables) "idx_ipt_dest" btree (dest) "idx_ipt_src" btree (source) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.03.2006, 11:45 |
|
||
|
INSERT в большую БД
|
|||
|---|---|---|---|
|
#18+
Может, формировать готовый файл и заливать его сразу в базу при помощи COPY FROM? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.03.2006, 13:41 |
|
||
|
INSERT в большую БД
|
|||
|---|---|---|---|
|
#18+
Идея неплохая,но файл нестандартный и его нужно дополнительно формировать.Можно поподробнее как работает COPY?Попробую этот вариант и сравню скорость.Все же интересно почему скорость при росте числа записей заметно падает. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.03.2006, 13:53 |
|
||
|
INSERT в большую БД
|
|||
|---|---|---|---|
|
#18+
Файл для COPY нужно формировать самому. Формат (разделители и прочее) указываешь в самом операторе COPY. Проще всего, наверное, формировать подобие CSV (comma separated values). Почитай доки по COPY там все несложно. Ускорение будет в том числе и от того, что все данные из файла будут заливаться в рамках одной транзакции. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.03.2006, 13:58 |
|
||
|
INSERT в большую БД
|
|||
|---|---|---|---|
|
#18+
Я в С и libpq не силен. Ты обрамляешь INSERT-ы в транзакцию? (лучше, я думаю, кусками по 1000 INSERT-ов) Есть ли возможность использовать PREPARED запросы? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.03.2006, 16:34 |
|
||
|
INSERT в большую БД
|
|||
|---|---|---|---|
|
#18+
mxlPostgresЕсть скрипт на Си,который читает файл и из него пишет в БД.При малом кол-ве записей в базе читает довольно быстро,но при кол-ве записей около 1 млн INSERTы выполняются медленно..... глупые вопросы... 1) делаете ли Вы после каждого PQexec вызов PQclear ? 2) одинаково ли время выполнения данной вставки локально, удалённо ? 3) пробовали ли Вы вставлять конец транзакции после 1000 (например) записей ? с уважением (круглый) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.03.2006, 19:44 |
|
||
|
INSERT в большую БД
|
|||
|---|---|---|---|
|
#18+
kolobok0 mxlPostgresЕсть скрипт на Си,который читает файл и из него пишет в БД.При малом кол-ве записей в базе читает довольно быстро,но при кол-ве записей около 1 млн INSERTы выполняются медленно..... глупые вопросы... 1) делаете ли Вы после каждого PQexec вызов PQclear ? 2) одинаково ли время выполнения данной вставки локально, удалённо ? 3) пробовали ли Вы вставлять конец транзакции после 1000 (например) записей ? с уважением (круглый) sprintf(str," BEGIN INSERT INTO iptables (bytes,prot,source,dest,date_second,time_second,date_first,time_first) \ VALUES ('%f','%s','%s','%s','%s','%s','%s','%s'); \ UPDATE iptables_last SET bytes='%s',date_last='%s',time_last='%s' \ WHERE dest='%s'; COMMIT ",bytes_new,prot,source,dest,PQgetvalue(res,0,2),PQgetvalue(res,0,3),dat_st_,time,bytes,dat_st_,time,dest); Вставил begin..commit,чтобы исключить потерю данных.COPY не подойдет из-за критичности к целостности данных,нужны транзакции. PQclear не выполняется,а разве можно этим ускорить процесс?? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.03.2006, 20:39 |
|
||
|
INSERT в большую БД
|
|||
|---|---|---|---|
|
#18+
Funny_FalconЯ в С и libpq не силен. Ты обрамляешь INSERT-ы в транзакцию? (лучше, я думаю, кусками по 1000 INSERT-ов) Есть ли возможность использовать PREPARED запросы? Для чего PREPARED?Сейчас объединю дату и время в одну колонку.Думаю,будет чуть быстрее. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.03.2006, 21:04 |
|
||
|
INSERT в большую БД
|
|||
|---|---|---|---|
|
#18+
mxlPostgres sprintf(str," BEGIN INSERT INTO iptables (bytes,prot,source,dest,date_second,time_second,date_first,time_first) \ VALUES ('%f','%s','%s','%s','%s','%s','%s','%s'); \ UPDATE iptables_last SET bytes='%s',date_last='%s',time_last='%s' \ WHERE dest='%s'; COMMIT ",bytes_new,prot,source,dest,PQgetvalue(res,0,2),PQgetvalue(res,0,3),dat_st_,time,bytes,dat_st_,time,dest); Вставил begin..commit,чтобы исключить потерю данных.COPY не подойдет из-за критичности к целостности данных,нужны транзакции. PQclear не выполняется,а разве можно этим ускорить процесс?? 1. Та не туды транзакции :) Стоит поставить раз 1000 - 10000 блоков SELECT/INSERT, Код: plaintext 1. 2. 3. 4. 5. 6. 7. P.S. О бэкапах не забываем :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.03.2006, 21:16 |
|
||
|
INSERT в большую БД
|
|||
|---|---|---|---|
|
#18+
mxlPostgres Для чего PREPARED?Сейчас объединю дату и время в одну колонку.Думаю,будет чуть быстрее. Чтобы серваку не надо было каждый раз полностью парсить инсерты и апдейты и строить для них запросы. PREPARED - уже построенный план запроса и только данные подставляй. Но основное - это все-таки транзакции. Если каждый инсерт в транзакции, то это миллион коммитов, а коммит не такая уж и дешевая операция. Если пачками по 1000 - то всего 1000 коммитов. Если явно транзакции не указываешь и автокоммит включен(он включен по умолчанию), то снова коммит на каждый инсерт - миллион коммитов. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.03.2006, 09:14 |
|
||
|
INSERT в большую БД
|
|||
|---|---|---|---|
|
#18+
ИМХО, лучше всего в такой ситуации использовать именно COPY FROM STDIN хорошо, что ты используешь libpq Работает все давольно просто и быстро... более быстрого способа занесения данных из файла в БД ты не найдешь Сначала выполняешь запрос типа Код: plaintext Код: plaintext А потом выполняешь команду завершения копирования PQputline(db->connection(), ru("\\.\n").local8Bit()); int res = PQendcopy(db->connection()); if (res!=0) {ошибка} ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.03.2006, 13:10 |
|
||
|
INSERT в большую БД
|
|||
|---|---|---|---|
|
#18+
mxlPostgresЕсть скрипт на Си,который читает файл и из него пишет в БД.При малом кол-ве записей в базе читает довольно быстро,но при кол-ве записей около 1 млн INSERTы выполняются медленно. Как можно ускорить вставку записей. Привожу запросы: sprintf(str,"SELECT bytes,dest,date_last,time_last FROM iptables_last WHERE dest='%s' and source='0.0.0.0/0'",dest); res=PQexec(conn,str); bytes_new=atof(bytes)-atof(PQgetvalue(res,0,0)); sprintf(str,"INSERT INTO iptables (bytes,prot,source,dest,date_second,time_second,date_first,time_first) \ VALUES ('%f','%s','%s','%s','%s','%s','%s','%s'); \ UPDATE iptables_last SET bytes='%s',date_last='%s',time_last='%s' \ WHERE dest='%s';",bytes_new,prot,source,dest,PQgetvalue(res,0,2),PQgetvalue(res,0,3),dat_st_,time,bytes,dat_st_,time,dest); res = PQexec(conn,str); 1. На Си не бывает скриптов. 2. В приведенном фрагменте, насколько я понимаю, содержится ошибка - не делается PQclear, что явно должно приводить к неприятным последствиям. 3. Как там дела с транзакциями? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.03.2006, 16:41 |
|
||
|
INSERT в большую БД
|
|||
|---|---|---|---|
|
#18+
mxlPostgres....PQclear не выполняется,а разве можно этим ускорить процесс?? Дело в том, что на мой взгляд могут быть следующие плоскости проблемы... а) нет освобождения ресурсов (и система каждый раз перераспределяет ресурсы, после их исчерпания - подкачивает кэш и прочее)... б) накапливаються отложенные операции изменений в самих таблицах (перенос самих значений)... в) возрастает кол-во данных в данной таблице.. первое как мне икаеться может быть по разным причинам... например нет освобождения ресурсов (отсюда косвенно вопрос про PQclear).. Либо не закрываються транзакции (или накапливаються в рамках одной транзакции).. Чтобы отсеять проблемы клиента от сервера - был вопрос про различные тук-тук к серваку...Локально, или удалённо.. Соответственно если ничего не меняеться - проблема сервака... накопление отложеных операций изменений по таблицам - пока не знаю, что сказать...вопросы тюнинга попахивает... по третьему пункту - перекликается с закрытием транзакции... Честно говоря сильно потрохи не шерстил постгресса, но вполне возможно различная (и существенно, по времени) обработка данных закомиченных и не закомиченных... ну где то так... ну и ышо мысля... попробуйте массивом запхнуть данные...да и вообще лучше наверное бинарные гнать сразу... хотя это упростит в основном жизнь клиенту, а не серваку... с уважением (круглый) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.03.2006, 19:31 |
|
||
|
|

start [/forum/topic.php?fid=53&msg=33584120&tid=2006584]: |
0ms |
get settings: |
8ms |
get forum list: |
13ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
71ms |
get topic data: |
11ms |
get forum data: |
3ms |
get page messages: |
53ms |
get tp. blocked users: |
2ms |
| others: | 257ms |
| total: | 424ms |

| 0 / 0 |
