powered by simpleCommunicator - 2.0.60     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / производительность insert
9 сообщений из 9, страница 1 из 1
производительность insert
    #33855437
zcrendel
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Приветсвую всех форумчан!

Проблема следующая:
из хранимой процедуры написанной на C необходимо вставить большое
количество записей (порядка 1 млн) в таблицу:

Код: plaintext
1.
2.
3.
4.
5.
6.
  create table "coupons_tmp" (
     id_s   int not null,
     id_e   int not null,
     type   int not null,
     liters int not null
   );


сейчас выполняю это вызовом в цикле следующей функции:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
void insert_into_tmp(int s, int e, int t, int l)
{
	char buf[ 1024 ];
	int ret;
	snprintf(buf, sizeof(buf), "INSERT INTO coupons_tmp (id_s,id_e,type,liters) VALUES (%d,%d,%d,%d); ",s,e,t,l);
	SPI_push();
	SPI_connect();
        ret = SPI_exec(buf,  0 );

	if (ret == SPI_OK_INSERT) {
	  SPI_freetuptable(SPI_tuptable);
	}

	SPI_finish();
	SPI_pop();
}

результат 760000 записей за 66-76сек (в зависимости от изменения параметров posgtresql.conf) т.е. ~ 12000 записей в секунду. Процессор 1.2ГГц.
Пробовал транзакции (по 10000 записей на транзакцию),
скорость практически не меняется. =\

Посгрес стартую с флагами -o '-F'

postgresql.conf:
Код: plaintext
1.
2.
3.
4.
5.
fsync=off
effective_cache_size =  5000 
work_mem= 10240 
... 
что еще нужно напишу

Это достаточная скорость для посгреса?
Как можно убыстрить добавление записей?

Для сравнения время копирования того же количества записей командой SQL
INSERT INTO coupons SELECT * FROM coupons_tmp ;
20 сек
...
Рейтинг: 0 / 0
производительность insert
    #33855438
zcrendel
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
пардон:
postmaster --version
postmaster (PostgreSQL) 8.1.3
...
Рейтинг: 0 / 0
производительность insert
    #33855529
Hordi
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Я бы по-любому изменил схему добавления, если возможно, конечно.

SPI_connect();

for(int i=0;i<1000000;++i){
SPI_exec(buf, 0);
}

SPI_finish();
...
Рейтинг: 0 / 0
производительность insert
    #33855584
> результат 760000 записей за 66-76сек

Посчитайте, какова скорость физической записи на диск.
...
Рейтинг: 0 / 0
производительность insert
    #33855974
zcrendel
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
PostgreSQL начинающий> результат 760000 записей за 66-76сек

Посчитайте, какова скорость физической записи на диск.

пожалуйста:

hdparm -t /dev/hda

/dev/hda:
Timing buffered disk reads: 60 MB in 3.02 seconds = 19.89 MB/sec
...
Рейтинг: 0 / 0
производительность insert
    #33855975
zcrendel
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
HordiЯ бы по-любому изменил схему добавления, если возможно, конечно.

SPI_connect();

for(int i=0;i<1000000;++i){
SPI_exec(buf, 0);
}

SPI_finish();

Раньше собственно было так, скорость была не больше (или не сильно больше).

Сейчас это невозможно, т.к. для этого придется буферизировать эти 1000000 записей ( а дополнительную память использовать жуть как не хочется), т.к. добавляемые записи выбираются из запроса. т.е. вызов функции добавления происходит так:

Код: 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.
    SPI_connect();
    
    ret = SPI_exec(command, cnt);      
    proc = SPI_processed;

    if (ret == SPI_OK_SELECT && SPI_processed >  0 )
    {
        TupleDesc tupdesc = SPI_tuptable->tupdesc;
        SPITupleTable *tuptable = SPI_tuptable;
        ....
        for (j =  1 ; j < proc ; j++)  {
            HeapTuple tuple = tuptable->vals[j]; int s,e,t,l; 

            s = DatumGetInt32(SPI_getbinval(tuple, tupdesc,  1 , &isnull));
            e = DatumGetInt32(SPI_getbinval(tuple, tupdesc,  2 , &isnull));
            t = DatumGetInt32(SPI_getbinval(tuple, tupdesc,  3 , &isnull));
            l = DatumGetInt32(SPI_getbinval(tuple, tupdesc,  4 , &isnull));
 
            ...
            insert_into_tmp(_s,_e,_t,_l);
            ...
        }        
       ...
    }

    ....
    SPI_finish();

этим и обусловлены вызов функций push() и pop() а такде connect() и finish() при добавлении...
...
Рейтинг: 0 / 0
производительность insert
    #33855978
> 19.89 MB/sec

Для одиночного диска приемлемый результат. Если есть желание ускорить работу, imho нужна более производительная дисковая подсистема.
...
Рейтинг: 0 / 0
производительность insert
    #33856791
Carrie
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
У меня получалось добиться ~80000 insert/сек с включенным fsync на обычном 80Гб IDE (sequental read по hdparm ~50Мб/сек), но на машинке 2x2.8Ггц Xeon. Не знаю насколько сильно здесь влияет производительность HDD, но мне помнится, что "затык" был в CPU.
Этого rate'а получилось достич только с исползованием SPI_saveplan+SPI_prepare и одного SPI_connect на все.
Также как и у вас INSERT'ы делались на данные, которые были получены из SELECT'а в этой же процедуре.
Не использовал SPI_push()/SPI_pop().

P.S.: версия pg 7.4.x. Могу выслать свои исходники.
...
Рейтинг: 0 / 0
Период между сообщениями больше года.
производительность insert
    #35476152
kamolsan
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
CarrieP.S.: версия pg 7.4.x. Могу выслать свои исходники.
Please.
...
Рейтинг: 0 / 0
9 сообщений из 9, страница 1 из 1
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / производительность insert
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]