Kata pengantar
Saya mempelajari PostgreSQL di rumah dan sangat menikmati pemrosesan data dalam jumlah besar. Saya menulis dalam C / C ++ pada kerangka kerja Qt. Sayangnya driver posting Qt tidak mendukung fungsionalitas yang diperlukan untuk memuat cepat. Oleh karena itu, saya menulis perpustakaan saya dalam C ++ untuk ini, dan sekarang saya ingin berbagi dengan Anda metode penambahan dan pustaka itu sendiri yang luar biasa.
Halo $ username!
Hari ini kita akan berbicara tentang pemuatan data yang cepat ke DBMS PostgreSQL (selanjutnya disebut sebagai `postik`). Kami akan melakukan ini melalui mekanisme COPY dengan transfer data melalui jaringan dalam format biner.
Pertama-tama, pertimbangkan keuntungan dari metode penambahan ini:
Kecepatan penambahan sangat cepat
Semuanya disebabkan oleh fakta bahwa kami menghilangkan kebutuhan untuk pemrosesan data (berbagai transformasi) seminimal mungkin, posting hanya perlu memeriksa apakah kami menggunakan format yang benar.
Kami tidak kehilangan data, berbeda dengan format teks.
Misalnya, bagaimana ini bisa terjadi dengan angka ganda. Kita tidak perlu mencari tahu berapa banyak tempat desimal sebelum dan sesudah koma desimal dalam metode ini. Data ditransmisikan `apa adanya`.
Dalam posting ini saya tidak akan mengungkapkan semua detail yang dijelaskan dalam dokumentasi. Kami hanya akan menulis metode penambahan yang mudah, mis. tanpa spesifik dan hal lainnya. Semua fungsi yang akan dipanggil dalam kode adalah fungsi dari pustaka "libpq-fe.h". Selain itu, semua kode akan ditulis dalam C / C ++.
Algoritma untuk membuat buffer biner
Struktur penyangga:
[buffer start header]
{data string}
{data string}
{data string}
... ... ...
{data string}
[ ]
:
COPY-
'P','G','C','O','P','Y','\n','\377','\r','\n','\0'
'\0','\0','\0','\0'
, OID – 16- 1
'\0','\0','\0','\0'
, . , .
( 13.1 ), .
:
int16_t , , . , , , .
:
1)
, ,
2)
, :
.
int64_t , . ( ). , - . , COPY TO
, .
0xff, 0xff
. , — , ( -1).
, —
string conninfo =
"host=127.0.0.1 port=5432 dbname=postgres user=postgres password=postgres connect_timeout=10";
PGconn *conn = PQconnectdb(conninfo.c_str());
// conninfo - ( connect_timeout )
COPY-
pg_result *res = PQexec(conn, cquery);
cquery COPY . COPY testtable5 ( col1, col2, col3, col4 ) FROM STDIN (format binary);
PQputCopyData(conn, buf, currentSize);
, buf – , currentSize — .
, . . 2-128 .
,
PQputCopyEnd(conn, NULL);
!
.
? , int16_t tmp = 2;
: 0x02, 0x00
0x00, 0x02
. . SPARC . , SPARC-, ( )
.
Qt:
db.open();
QSqlQuery query(db);
query.prepare("insert into testtable5 ( col1, col2, col3, col4 ) values (?,?,?,?);");
for(int i=0; i<20000000; i++)
{
query.addBindValue("column1");
query.addBindValue(double(12983712987.4383453947384734853872837));
query.addBindValue(int(12345678));
query.addBindValue(float(123.4567));
query.exec();
}
( ) 10.000 - Y, - - X.
COPY INSERT .
- INSERT- .
- INSERT- .
- COPY- .
- COPY- .
INSERT .
- INSERT- .
- INSERT- .
COPY .
- COPY- .
- COPY- .
.
:
10.000 ( ), :
12.620 INSERT
12.050 INSERT
150 COPY
120 COPY
... COPY. , .
— . , , , .
P.S.: , .
.