Acelere la carga de grandes volúmenes en PostgreSQL utilizando COPY from STDIN binary

Prefacio





Estoy aprendiendo PostgreSQL en casa y realmente disfruto procesando grandes cantidades de datos. Estoy escribiendo en C / C ++ en el marco Qt. Desafortunadamente, el controlador de correos Qt no admite la funcionalidad requerida para una carga rápida. Por lo tanto, escribí mi biblioteca en C ++ para esto, y ahora quiero compartir con ustedes este maravilloso método de agregar y la biblioteca en sí.









¡Hola, $ username!





Hoy hablaremos sobre la carga rápida de datos en PostgreSQL DBMS (en lo sucesivo, `postik`). Lo haremos a través del mecanismo COPY con la transferencia de datos a través de la red en formato binario.









En primer lugar, considere las ventajas de este método de agregar:





  • Velocidad de adición muy rápida





    Todo se debe a que eliminamos al mínimo la necesidad de procesamiento de datos (varias transformaciones), la publicación solo tiene que verificar si estamos usando el formato correcto.





  • No perdemos datos, a diferencia del formato de texto.





    Por ejemplo, ¿cómo puede suceder esto con un número doble? No necesitaremos averiguar cuántos dígitos antes y después del punto decimal en este método. Los datos se transmiten "tal cual".









, . , .. . , — “libpq-fe.h”. - /++.





:





[ ]





{ }





{ }





{ }





. . .





{ }





[ ]













:





  • 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.: , .





.








All Articles