Каков ваш совет по настройке PostgreSQL, чтобы BLOB можно было быстро написать?Как быстро вставить BLOB в PostgreSQL?
Мы используем PostgreSQL для ввода BLOB с высокой скоростью.
- Мы называем lo_write() примерно 220 раз в секунду.
- Мы пишем примерно 30 Кбайт двоичных данных за lo_write().
- Это эквивалентно примерно 6 Мбайт/с.
Наш компьютер - RAID-5, поэтому скорость записи составляет около 200 МБ/с.
Мы уже настроили postgresql.conf иметь следующее:
- мы изменили shared_buffers = 1GB
- мы выключили FSYNC
- logging_collector = выкл (в значительной степени все, что связано с Протоколирование выключено)
Мы убедились, что если мы не храним BLOB как часть нашего запроса INSERT, то PgSql будет поддерживать штраф. Только когда мы храним BLOB как часть нашего запроса, он замедляется.
EDIT: Я использую Windows XP/Server. Я использую Pgsql 8.3 с PostGIS 1.3.6. Причина, по которой мне нужно было хранить BLOB в БД, - это то, что мое приложение требует от меня поиска этих BLOB в режиме реального времени.
Основание: Наше приложение представляет собой высокоэффективную обработку сигналов в реальном времени, где мы храним наши сигналы в базе данных как BLOB.
EDIT: Это код на C++, который использовался для выполнения теста. По-видимому, мы получаем около 16 МБ/с в нашей конфигурации RAID.
#include "libpq-fe.h"
#include "libpq/libpq-fs.h"
#include <sstream>
#include <iostream>
#include <tbb/tick_count.h>
void test()
{
std::stringstream stst;
stst << "user=postgres password=1234 dbname=test_db";
PGconn* conn = PQconnectdb(stst.str().c_str());
if (PQstatus(conn) != CONNECTION_OK)
{
throw std::exception("failed to connect To DB engine: ");
}
const int dataSize = 18512;
char* data = (char*) malloc(dataSize);
const int count = 10000;
tbb::tick_count t0 = tbb::tick_count::now();
for(int idx = 0; idx < count; idx++)
{
// Insert acoustic binary into large object table "pg_largeobject"
Oid objectId;
int lobj_fd;
PGresult *res;
res = PQexec(conn, "begin");
PQclear(res);
objectId = lo_creat(conn, INV_READ|INV_WRITE);
if (objectId == 0)
{
throw std::exception("AddAcousticTable: Cannot create large object\n");
}
lobj_fd = lo_open(conn, objectId, INV_WRITE);
const unsigned int writeBytes = lo_write(conn, lobj_fd, data, dataSize);
if (writeBytes != dataSize)
{
std::stringstream msg;
msg << "PsSasDataDB::AddToAcousticTable(): Incorrect number of bytes written for large object ";
msg << writeBytes;
throw std::exception(msg.str().c_str());
}
lo_close(conn, lobj_fd);
res = PQexec(conn, "end");
PQclear(res);
}
tbb::tick_count t1 = tbb::tick_count::now();
std::cout << "Performance: " << (double(count*dataSize)/(t1-t0).seconds())/(1024.0*1024.0) << " MB/seconds";
free(data);
}
int main()
{
try
{
test();
}
catch(std::exception e)
{
std::cerr << e.what();
}
return 0;
}
Какие версии (OS и PG)? Почему вы выбрали крупные объекты? По-видимому, консенсус заключается в том, что просто хранение файлов в файловой системе работает лучше, если у вас нет разумного основания использовать BLOB-базы данных. – kquinn
Я отредактировал вопрос, чтобы предоставить ответы на ваши комментарии. Благодарю. – sivabudh
Если вы могли бы опубликовать достаточно вашей схемы базы данных, что пример кода будет работать против этого подмножества, это позволит другим людям запустить ваш тест и получить гораздо лучшие данные. Просто наличие кода на C++ без возможности попробовать запустить это не так полезно. –