Обсуждение: PostgreSQL vs MySQL : strange results on insertion
Hello,
I'm making some tests to migrate a MySQL DB to PostgreSQL DB. I realized a small program in C which does the same thing
forMySQL (C API) and PostgreSQL (libpq) : 10000 insertion in a quite simple base.
My DB :
|-----------------|----------------------------------------------|
| test |
| id | auto_increment (or serial for postgreSQL) |
| type_int | INT (or integer) |
| type_varchar | varchar(255) |
| type_int2 | INT (or integer) |
| type_text | text |
|-----------------|----------------------------------------------|
/* -------------------- MySQL code : -------------------- */
#define INSERTION "INSERT INTO test (type_int, type_varchar,type_tinyint,type_text) VALUES (%d,\'essai de chaine de
caractère\',100,\'MAJUSCULESet minuscules\'"
int main(int argc, char **argv) {
MYSQL mysql;
unsigned int i;
char mquery(1000);
MYSQL_RES *mysql_row;
mysql_init(&mysql);
if (mysql_real_connect(&mysql, NULL, "user", NULL, "bd", 0, NULL, 0)) {
for (i=0;i<=10000;i++) {
sprintf(mquery,INSERTION,i);
if ((mysql_query(&mysql,mquery)!=0) {
printf("sql query error (%s) : %s\n",mquery,mysql_error(&mysql));
mysql_close(&mysql);
return 0;
}
}
mysql_close(&mysql);
}
else {
printf("sql connection error : %s\n",mysql_error(&mysql));
return 0;
}
return 0;
}
/* -------------------- PostgreSQL code : -------------------- */
#define INSERTION "INSERT INTO test (type_int, type_varchar,type_tinyint,type_text) VALUES (%d,\'essai de chaine de
caractère\',100,\'MAJUSCULESet minuscules\'"
int main(int argc, char **argv) {
PGconn *conn;
unsigned int i;
char mquery(1000);
PGresult *res;
conn=PQconnectdb("dbname=db user=user");
if (PQstatus(conn) == CONNECTION_OK) {
for (i=0;i<=10000;i++) {
sprintf(mquery,INSERTION,i);
res=PQexec(conn,mquery);
if (PQresultstatus(res)!= PGRES_COMMAND_OK) {
printf("sql query error (%s) : %s\n",mquery,PQresultErrorMessage(res));
PQclear(res);
PQfinish(conn);
return 0;
}
}
PQclear(res);
PQfinish(conn);
}
else {
printf("sql connection error : %s\n",PQerrorMessage(conn));
return 0;
}
return 0;
}
I launch these programs on my computer : Linux Debian with MySQL 3.23.51 and PostgreSQL 7.2.1 (installation by default
with'apt-get install').
Time to realize 10000 insertions with MySQL:
$ time ./test__mysql
real 0m1.500s
user 0m0.150s
sys 0m0.090s
(between 1 and 2 seconds)
Time to realize 10000 insertions with PostgreSQL:
$time ./test_postgresql
real 0m28.568s
user 0m0.390s
sys 0m0.270s
(between 28 and 30 seconds !!!.... )
Very strange, isn't it ? Is there something in PostgreSQL's C API that I didn't understand ? Subtleties during the
configuration? I do not want to believe that PostgreSQL is 15 times slower than MySQL !
Thank you for any comment, remark and correction!
Florent Paul
-------------------------------------------------------------
NetCourrier, votre bureau virtuel sur Internet : Mail, Agenda, Clubs, Toolbar...
Web/Wap : www.netcourrier.com
Téléphone/Fax : 08 92 69 00 21 (0,34 TTC/min)
Minitel: 3615 NETCOURRIER (0,15 TTC/min)
On Thu, 5 Sep 2002 fpaul@netcourrier.com wrote: > I launch these programs on my computer : Linux Debian with MySQL 3.23.51 and PostgreSQL 7.2.1 (installation by defaultwith 'apt-get install'). > Time to realize 10000 insertions with MySQL: > $ time ./test__mysql > > real 0m1.500s > user 0m0.150s > sys 0m0.090s > (between 1 and 2 seconds) > > Time to realize 10000 insertions with PostgreSQL: > $time ./test_postgresql > > real 0m28.568s > user 0m0.390s > sys 0m0.270s > (between 28 and 30 seconds !!!.... ) > > Very strange, isn't it ? Is there something in PostgreSQL's C API that I didn't understand ? Subtleties during the configuration? I do not want to believe that PostgreSQL is 15 times slower than MySQL ! > Thank you for any comment, remark and correction! Not really all that strange. Again, this is a side effect of using a transactionally oriented database. Try adding a begin; and end; pair around your inserts in postgresql and see if it runs faster.
fpaul@netcourrier.com a écrit:
> Hello,
>
> I'm making some tests to migrate a MySQL DB to PostgreSQL DB. I realized a small program in C which does the same
thingfor MySQL (C API) and PostgreSQL (libpq) : 10000 insertion in a quite simple base.
> My DB :
> |-----------------|----------------------------------------------|
> | test |
> | id | auto_increment (or serial for postgreSQL) |
> | type_int | INT (or integer) |
> | type_varchar | varchar(255) |
> | type_int2 | INT (or integer) |
> | type_text | text |
> |-----------------|----------------------------------------------|
>
> /* -------------------- MySQL code : -------------------- */
> #define INSERTION "INSERT INTO test (type_int, type_varchar,type_tinyint,type_text) VALUES (%d,\'essai de chaine de
caractère\',100,\'MAJUSCULESet minuscules\'"
>
> int main(int argc, char **argv) {
> MYSQL mysql;
> unsigned int i;
> char mquery(1000);
> MYSQL_RES *mysql_row;
>
> mysql_init(&mysql);
> if (mysql_real_connect(&mysql, NULL, "user", NULL, "bd", 0, NULL, 0)) {
> for (i=0;i<=10000;i++) {
> sprintf(mquery,INSERTION,i);
> if ((mysql_query(&mysql,mquery)!=0) {
> printf("sql query error (%s) : %s\n",mquery,mysql_error(&mysql));
> mysql_close(&mysql);
> return 0;
> }
> }
> mysql_close(&mysql);
> }
> else {
> printf("sql connection error : %s\n",mysql_error(&mysql));
> return 0;
> }
> return 0;
> }
>
> /* -------------------- PostgreSQL code : -------------------- */
> #define INSERTION "INSERT INTO test (type_int, type_varchar,type_tinyint,type_text) VALUES (%d,\'essai de chaine de
caractère\',100,\'MAJUSCULESet minuscules\'"
>
> int main(int argc, char **argv) {
> PGconn *conn;
> unsigned int i;
> char mquery(1000);
> PGresult *res;
>
> conn=PQconnectdb("dbname=db user=user");
> if (PQstatus(conn) == CONNECTION_OK) {
> for (i=0;i<=10000;i++) {
> sprintf(mquery,INSERTION,i);
> res=PQexec(conn,mquery);
> if (PQresultstatus(res)!= PGRES_COMMAND_OK) {
> printf("sql query error (%s) : %s\n",mquery,PQresultErrorMessage(res));
> PQclear(res);
> PQfinish(conn);
> return 0;
> }
> }
> PQclear(res);
> PQfinish(conn);
> }
> else {
> printf("sql connection error : %s\n",PQerrorMessage(conn));
> return 0;
> }
> return 0;
> }
>
> I launch these programs on my computer : Linux Debian with MySQL 3.23.51 and PostgreSQL 7.2.1 (installation by
defaultwith 'apt-get install').
> Time to realize 10000 insertions with MySQL:
> $ time ./test__mysql
>
> real 0m1.500s
> user 0m0.150s
> sys 0m0.090s
> (between 1 and 2 seconds)
>
> Time to realize 10000 insertions with PostgreSQL:
> $time ./test_postgresql
>
> real 0m28.568s
> user 0m0.390s
> sys 0m0.270s
> (between 28 and 30 seconds !!!.... )
>
> Very strange, isn't it ? Is there something in PostgreSQL's C API that I didn't understand ? Subtleties during the
configuration? I do not want to believe that PostgreSQL is 15 times slower than MySQL !
> Thank you for any comment, remark and correction!
>
> Florent Paul
pgsql launches 10000 transactions (I don't know if mysql does this)
You should launch a "BEGIN;" before your 10000 insert and an "END;" after.
or better: test your server and discover the proper number of insert
to be done in one transaction to have the max speed.
For mine, 3000 insert for each transaction is good.
> Time to realize 10000 insertions with PostgreSQL:
> $time ./test_postgresql
>
> real 0m28.568s
> user 0m0.390s
> sys 0m0.270s
> (between 28 and 30 seconds !!!.... )
>
> Very strange, isn't it ? Is there something in PostgreSQL's C API that I
> didn't understand ? Subtleties during the configuration ? I do not want to
> believe that PostgreSQL is 15 times slower than MySQL ! Thank you for any
> comment, remark and correction!
On my system (compiled for profiling, debugging and slow disk) it takes 2 minutes without transactions, and 4.5 seconds
withtransactions:
#include <stdio.h>
#include <libpq-fe.h>
#define INSERTION "INSERT INTO test (type_int, type, type_int2, type_text) VALUES (%d,\'essai de chaine
decaractère\',100,\'MAJUSCULESet minuscules\')"
int main(int argc, char **argv) {
PGconn *conn;
unsigned int i;
char mquery[1000];
PGresult *res;
conn=PQconnectdb("dbname=mario");
if (PQstatus(conn) == CONNECTION_OK) {
res=PQexec(conn,"begin");
PQclear(res);
for (i=0;i<=10000;i++) {
sprintf(mquery,INSERTION,i);
res=PQexec(conn,mquery);
if (PQresultStatus(res)!= PGRES_COMMAND_OK) {
printf("sql query error (%s) : %s\n",
mquery,PQresultErrorMessage(res));
PQclear(res);
res=PQexec(conn,"commit ");
PQclear(res);
PQfinish(conn);
return 0;
}
}
PQclear(res);
PQfinish(conn);
}
else {
printf("sql connection error :%s\n",PQerrorMessage(conn));
return 0;
}
return 0;
}
best regards,
mario weilguni