Всем читающим это сообщение доброго времени суток.Возник вопрос с производительностью сервера Postgres 9.5 при работе через libpq из приложения, написанного на С.
Тестировался вызов (10000 раз) хранимой ф-ции из скрипта PGSQL и из приложения. Результаты:
Скрипт: 503 msec. (19880.71570 операций вставки в секунду)
Приложение: 71.241997 sec. (140.36664 операций вставки в секунду)
Разница в 141.63418 раз!!!111
В чём может быть проблема такой деградации?
Описание системы:
$ uname -a
Linux localhost.dev.resolute.ru 3.9.4 #3 SMP Tue May 28 14:26:24 EDT 2013 x86_64 x86_64 x86_64 GNU/Linux$ /usr/web/bin/pg_ctl --version
pg_ctl (PostgreSQL) 9.5.3
Вызываемая процедура:
create or replace function test_job(
in v_i_id int8,
out v_o_id int8
)
as
$$
begin
select n into v_o_id from test_t where n = 100;
insert into test_t(n) values (v_i_id);
end;
$$ language plpgsql
Тестовый скрипт:
do
$$
declare v_o_res int8;
begin
for i in 1..10000 loop
select test_job(i::int8) into v_o_res;
end loop;
end;
$$
Код приложения (С)
#include <stdio.h>
#include <libpq-fe.h>
#include <sys/time.h>#define uint64_t unsigned long long
uint64_t htonll(uint64_t host_longlong) {
int x = 1;
if(*(char *)&x == 1)
return ((((uint64_t)htonl(host_longlong)) << 32) + htonl(host_longlong >> 32));
else
return host_longlong;
}
int main() {
PGconn *conn;
const char *keywords[7] = {"host", "port", "dbname", "user", "password", "client_encoding", NULL};
const char *values[7] = {"/usr/web/run", "5434", "_login", "_schema", "_passwd", "UTF8", NULL};
int rowCount, colCount, i, j;
PGresult *res;
ExecStatusType status;
struct timeval tv;
conn = PQconnectdbParams(keywords, values, 0);
if (PQstatus(conn) == CONNECTION_BAD) {
printf("Не удается подключиться к базе данных\n%s\n", PQerrorMessage(conn));
return 1;
}
gettimeofday(&tv, NULL);
long long t = tv.tv_sec*1000000 + tv.tv_usec;
const char *paramValues[1];
int paramLengths[1];
int paramBinary[1];
for(i=0; i<10000; i++) {
long long id = htonll(i);
paramValues[0] = (char*)&id;
paramLengths[0] = 8;
paramBinary[0] = 1;
res = PQexecParams(conn,
"select test_job($1::int8)",
1, // кол-во параметров
NULL, // backend узнает тип параметров из текста запроса
paramValues,
paramLengths,
paramBinary,
0 // результат вернуть как текст
);
status = PQresultStatus(res);
if((status != PGRES_COMMAND_OK)&&(status != PGRES_TUPLES_OK)) {
printf("ERROR: %s\n", PQresultErrorMessage(res));
PQclear(res);
return 0;
}
//printf("%s\n", PQgetvalue(res, 0, 0));
}
gettimeofday(&tv, NULL);
t = (long long)(tv.tv_sec*1000000 + tv.tv_usec) - t;
printf("\ntime: %f sec\n", ((float)t)/1000000);
PQclear(res);
PQfinish(conn);
return 0;
}