Vorwort
Ich lerne PostgreSQL zu Hause und genieße es wirklich, große Datenmengen zu verarbeiten. Ich schreibe in C / C ++ auf dem Qt-Framework. Leider unterstützt der Qt-Post-Treiber nicht die für das schnelle Laden erforderlichen Funktionen. Deshalb habe ich meine Bibliothek in C ++ dafür geschrieben, und jetzt möchte ich diese wunderbare Methode des Hinzufügens und die Bibliothek selbst mit Ihnen teilen.
Hallo $ Benutzername!
Heute werden wir über das schnelle Laden von Daten in PostgreSQL DBMS (im Folgenden als "postik" bezeichnet) sprechen. Wir werden dies durch den COPY-Mechanismus mit der Übertragung von Daten über das Netzwerk in einem Binärformat tun.
Betrachten Sie zunächst die Vorteile dieser Methode des Hinzufügens:
Sehr schnelle Addiergeschwindigkeit
Alles ist darauf zurückzuführen, dass wir die Notwendigkeit der Datenverarbeitung (verschiedene Transformationen) auf ein Minimum reduzieren. Der Beitrag muss nur prüfen, ob wir das richtige Format verwenden.
Im Gegensatz zum Textformat verlieren wir keine Daten.
Wie kann dies beispielsweise mit einer doppelten Zahl geschehen? Wir müssen bei dieser Methode nicht herausfinden, wie viele Stellen vor und nach dem Dezimalpunkt stehen. Die Daten werden "wie sie sind" übertragen.
In diesem Beitrag werde ich nicht alle Details offenlegen, die in der Dokumentation beschrieben sind. Wir werden nur eine einfache Additionsmethode schreiben, d. H. ohne Einzelheiten und andere Dinge. Alle Funktionen, die im Code aufgerufen werden, sind Funktionen aus der Bibliothek „libpq-fe.h“. Außerdem wird der gesamte Code in C / C ++ geschrieben.
Algorithmus zum Erstellen eines Binärpuffers
Pufferstruktur:
[Pufferstart-Header]
{Datenzeichenfolge}
{Datenzeichenfolge}
{Datenzeichenfolge}
... ... ...
{Datenzeichenfolge}
[ ]
:
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. , .
— . , , , .
GitHub
COPY
P.S.: , .
.