Thread: Postgresql INSERT speed (how to improve performance)?

Postgresql INSERT speed (how to improve performance)?

From
"Lim Berger"
Date:
Hi,

I've googled and yahooed and most of the performance tweaks suggested
cover SELECT speed, some cover COPY speed with things like turning
fsync off and such. But I still have not found how to improve regular
INSERT speed on Postgresql.

I have a table in MySQL with three compound indexes. I have only three
columns from this table also in PostgreSQL, which serves as a cache of
sorts for fast queries, and this table has only ONE main index on the
primary key!

INSERTing into MySQL takes 0.0001 seconds per insert query.
INSERTing into PgSQL takes 0.871 seconds per (much smaller) insert query.

What can I do to improve this performance? What could be going wrong
to elicit such poor insertion performance from Postgresql?

Thanks.

Re: Postgresql INSERT speed (how to improve performance)?

From
Tony Caduto
Date:
Lim Berger wrote:
>
> INSERTing into MySQL takes 0.0001 seconds per insert query.
> INSERTing into PgSQL takes 0.871 seconds per (much smaller) insert query.
>
> What can I do to improve this performance? What could be going wrong
> to elicit such poor insertion performance from Postgresql?
>
> Thanks.
>
> ---------------------------(end of broadcast)---------------------------
> TIP 6: explain analyze is your friend
>
>


The first thing I would ask is what type of DB engine are you using
while doing the inserts on MySQL?
The reason MySQL is doing the inserts faster is it does not have
transaction support if you are using anything other than InnoDB.

With that said you can increase your insert performance by simply using
a transaction and committing every 1000 rows or so.

If you do this you will see a huge performance increase.

hope that helps.

Tony Caduto
AM Software Design
http://www.amsoftwaredesign.com
Home of Lightning Admin for PostgreSQL and MySQL



Re: Postgresql INSERT speed (how to improve performance)?

From
"Andrej Ricnik-Bay"
Date:
On 8/14/07, Lim Berger <straightfwd007@gmail.com> wrote:

> INSERTing into MySQL takes 0.0001 seconds per insert query.
> INSERTing into PgSQL takes 0.871 seconds per (much smaller) insert query.
>
> What can I do to improve this performance? What could be going wrong
> to elicit such poor insertion performance from Postgresql?
MySQL might not be writing the data straight out
to disk ... just a guess.


> Thanks.
Cheers,
Andrej

Re: Postgresql INSERT speed (how to improve performance)?

From
"Lim Berger"
Date:
On 8/14/07, Andrej Ricnik-Bay <andrej.groups@gmail.com> wrote:
> On 8/14/07, Lim Berger <straightfwd007@gmail.com> wrote:
>
> > INSERTing into MySQL takes 0.0001 seconds per insert query.
> > INSERTing into PgSQL takes 0.871 seconds per (much smaller) insert query.
> >
> > What can I do to improve this performance? What could be going wrong
> > to elicit such poor insertion performance from Postgresql?
> MySQL might not be writing the data straight out
> to disk ... just a guess.
>



The MYSQL table is MYISAM, yes, so no transaction support. I would
like PgSQL to do the same. These are not a batch of queries so I
cannot bundle them inside a transaction. These are individual
submissions from the web.

To make PG behave in the above manner, I have the following in my conf:

commit_delay = 0
fsync = on
wal_buffers=64
checkpoint_segments=64
checkpoint_timeout=900

Am I missing something? (I may well be). Would explicitly issuing a
"COMMIT" command help at all? Should I do the following:

BEGIN TRANSACTION;
INSERT INTO...;
COMMIT;

Would this be faster?

Re: Postgresql INSERT speed (how to improve performance)?

From
Tom Lane
Date:
"Lim Berger" <straightfwd007@gmail.com> writes:
> I have a table in MySQL with three compound indexes. I have only three
> columns from this table also in PostgreSQL, which serves as a cache of
> sorts for fast queries, and this table has only ONE main index on the
> primary key!

> INSERTing into MySQL takes 0.0001 seconds per insert query.
> INSERTing into PgSQL takes 0.871 seconds per (much smaller) insert query.

You had better provide some details, because that's completely out of
line, assuming that by "insert query" you mean insert one row.  For a
comparison point, I get this on a rather old and slow machine:

regression=# create table t1 (f1 int, f2 int, f3 int,
regression(# unique(f1,f2),
regression(# unique(f2,f3),
regression(# unique(f1,f3));
NOTICE:  CREATE TABLE / UNIQUE will create implicit index "t1_f1_key" for table "t1"
NOTICE:  CREATE TABLE / UNIQUE will create implicit index "t1_f2_key" for table "t1"
NOTICE:  CREATE TABLE / UNIQUE will create implicit index "t1_f1_key1" for table "t1"
CREATE TABLE
regression=# \timing
Timing is on.
regression=# insert into t1 values(1,2,3);
INSERT 0 1
Time: 9.048 ms
regression=# insert into t1 values(1,7,4);
INSERT 0 1
Time: 4.357 ms
regression=# insert into t1 values(11,7,5);
INSERT 0 1
Time: 3.998 ms
regression=#

            regards, tom lane

Re: Postgresql INSERT speed (how to improve performance)?

From
Tony Caduto
Date:
Lim Berger wrote:
> On 8/14/07, Andrej Ricnik-Bay <andrej.groups@gmail.com> wrote:
>
>> On 8/14/07, Lim Berger <straightfwd007@gmail.com> wrote:
>>
>>
>>> INSERTing into MySQL takes 0.0001 seconds per insert query.
>>> INSERTing into PgSQL takes 0.871 seconds per (much smaller) insert query.
>>>
>>> What can I do to improve this performance? What could be going wrong
>>> to elicit such poor insertion performance from Postgresql?
>>>
Lim,

Are you sure you are not confusing Seconds VS Milliseconds from one
query tool to the other?

What tools are you using to show the query times?

As far as I know the psql command line tool shows milliseconds not seconds.

You should probably post some more info like the actual insert query
used and the table.

I have never seen a insert take that long even a big one, unless you
have some network latency to the PGSQL host and it's causing the time to
be messed up on the client.

Might also help to let us know exactly how you are timing this stuff.
Are you connecting remotely via PSQL or are you connecting via SSH and
running psql or mysql that way?


Later,

Tony Caduto
AM Software Design
http://www.amsoftwaredesign.com
Home of PG Lightning Admin for PostgreSQL and MySQL

Re: Postgresql INSERT speed (how to improve performance)?

From
"Lim Berger"
Date:
On 8/14/07, Tom Lane <tgl@sss.pgh.pa.us> wrote:
> "Lim Berger" <straightfwd007@gmail.com> writes:
> > I have a table in MySQL with three compound indexes. I have only three
> > columns from this table also in PostgreSQL, which serves as a cache of
> > sorts for fast queries, and this table has only ONE main index on the
> > primary key!
>
> > INSERTing into MySQL takes 0.0001 seconds per insert query.
> > INSERTing into PgSQL takes 0.871 seconds per (much smaller) insert query.
>
> You had better provide some details, because that's completely out of
> line, assuming that by "insert query" you mean insert one row.  For a
> comparison point, I get this on a rather old and slow machine:
>
> regression=# create table t1 (f1 int, f2 int, f3 int,
> regression(# unique(f1,f2),
> regression(# unique(f2,f3),
> regression(# unique(f1,f3));
> NOTICE:  CREATE TABLE / UNIQUE will create implicit index "t1_f1_key" for table "t1"
> NOTICE:  CREATE TABLE / UNIQUE will create implicit index "t1_f2_key" for table "t1"
> NOTICE:  CREATE TABLE / UNIQUE will create implicit index "t1_f1_key1" for table "t1"
> CREATE TABLE
> regression=# \timing
> Timing is on.
> regression=# insert into t1 values(1,2,3);
> INSERT 0 1
> Time: 9.048 ms
> regression=# insert into t1 values(1,7,4);
> INSERT 0 1
> Time: 4.357 ms
> regression=# insert into t1 values(11,7,5);
> INSERT 0 1
> Time: 3.998 ms
> regression=#



Thanks Tom. But on a newly minted table, sure, the performance would
be great. My table now has about 3 million rows (both in MySQL and
PG).

Here's the table definition:


                             Table "public.cachedstats"
        Column         |         Type          |          Modifiers
-----------------------+-----------------------+------------------------------
 id                    | bigint                | not null
 prof_name             | character varying(20) | not null
 notes                 | text                  | not null
 inform_prof_on_change | character(1)          | not null default 'N'::bpchar

Indexes:
    "cachedstats_pkey" PRIMARY KEY, btree (id)
    "idx_cachedstats_unique_prof_name" UNIQUE, btree (alias)


How can I test the bottleneck?

Re: Postgresql INSERT speed (how to improve performance)?

From
"Lim Berger"
Date:
On 8/14/07, Lim Berger <straightfwd007@gmail.com> wrote:
> On 8/14/07, Tom Lane <tgl@sss.pgh.pa.us> wrote:
> > "Lim Berger" <straightfwd007@gmail.com> writes:
> > > I have a table in MySQL with three compound indexes. I have only three
> > > columns from this table also in PostgreSQL, which serves as a cache of
> > > sorts for fast queries, and this table has only ONE main index on the
> > > primary key!
> >
> > > INSERTing into MySQL takes 0.0001 seconds per insert query.
> > > INSERTing into PgSQL takes 0.871 seconds per (much smaller) insert query.
> >
> > You had better provide some details, because that's completely out of
> > line, assuming that by "insert query" you mean insert one row.  For a
> > comparison point, I get this on a rather old and slow machine:
> >
> > regression=# create table t1 (f1 int, f2 int, f3 int,
> > regression(# unique(f1,f2),
> > regression(# unique(f2,f3),
> > regression(# unique(f1,f3));
> > NOTICE:  CREATE TABLE / UNIQUE will create implicit index "t1_f1_key" for table "t1"
> > NOTICE:  CREATE TABLE / UNIQUE will create implicit index "t1_f2_key" for table "t1"
> > NOTICE:  CREATE TABLE / UNIQUE will create implicit index "t1_f1_key1" for table "t1"
> > CREATE TABLE
> > regression=# \timing
> > Timing is on.
> > regression=# insert into t1 values(1,2,3);
> > INSERT 0 1
> > Time: 9.048 ms
> > regression=# insert into t1 values(1,7,4);
> > INSERT 0 1
> > Time: 4.357 ms
> > regression=# insert into t1 values(11,7,5);
> > INSERT 0 1
> > Time: 3.998 ms
> > regression=#
>
>
>
> Thanks Tom. But on a newly minted table, sure, the performance would
> be great. My table now has about 3 million rows (both in MySQL and
> PG).
>
> Here's the table definition:
>
>
>                              Table "public.cachedstats"
>         Column         |         Type          |          Modifiers
> -----------------------+-----------------------+------------------------------
>  id                    | bigint                | not null
>  prof_name             | character varying(20) | not null
>  notes                 | text                  | not null
>  inform_prof_on_change | character(1)          | not null default 'N'::bpchar
>
> Indexes:
>     "cachedstats_pkey" PRIMARY KEY, btree (id)
>     "idx_cachedstats_unique_prof_name" UNIQUE, btree (alias)
>
>
> How can I test the bottleneck?
>



Btw, the query is as simple as:

INSERT INTO cachedstats
    (id, prof_name, notes, inform_prof_on_change)
VALUES
    (3190087, 'Lim Berger', '.....text of about 1000 chars', 'Y');

I am testing through PHP microtime function. The query is administered
through pg_query() function of PHP. I know there could be some latency
coming in from the PHP's PG functions' overhead, but not such an order
of magnitude different from "mysqli_query"!  (I hope -- because this
is quite a common real-world situation I would think).

Re: Postgresql INSERT speed (how to improve performance)?

From
Tom Lane
Date:
"Lim Berger" <straightfwd007@gmail.com> writes:
>> Thanks Tom. But on a newly minted table, sure, the performance would
>> be great. My table now has about 3 million rows (both in MySQL and
>> PG).

Well, INSERT speed is really not very dependent on table size (else I'd
have inserted a few zillion rows before timing it).  Personally I rather
like Tony's theory that you've gotten confused about what the timing
units are.

> Btw, the query is as simple as:

> INSERT INTO cachedstats
>     (id, prof_name, notes, inform_prof_on_change)
> VALUES
>     (3190087, 'Lim Berger', '.....text of about 1000 chars', 'Y');

These are the sorts of details that you can't leave out if you want
an intelligent response.

> I am testing through PHP microtime function.

Well, that brings up a whole host of questions, starting with whether
the PHP DB adapter you're using is any good.  Can you replicate similar
timings if you feed the same query into plain psql?

            regards, tom lane

Re: Postgresql INSERT speed (how to improve performance)?

From
Gregory Stark
Date:
"Lim Berger" <straightfwd007@gmail.com> writes:

> Here's the table definition:
>
>                              Table "public.cachedstats"
>         Column         |         Type          |          Modifiers
> -----------------------+-----------------------+------------------------------
>  id                    | bigint                | not null
>  prof_name             | character varying(20) | not null
>  notes                 | text                  | not null
>  inform_prof_on_change | character(1)          | not null default 'N'::bpchar
>
> Indexes:
>     "cachedstats_pkey" PRIMARY KEY, btree (id)
>     "idx_cachedstats_unique_prof_name" UNIQUE, btree (alias)

What's "alias"?


--
  Gregory Stark
  EnterpriseDB          http://www.enterprisedb.com

Re: Postgresql INSERT speed (how to improve performance)?

From
John DeSoi
Date:
On Aug 13, 2007, at 11:54 PM, Lim Berger wrote:

> I am testing through PHP microtime function. The query is administered
> through pg_query() function of PHP. I know there could be some latency
> coming in from the PHP's PG functions' overhead, but not such an order
> of magnitude different from "mysqli_query"!  (I hope -- because this
> is quite a common real-world situation I would think).

You might also try using prepared statements for your inserts (see
PHP's pg_prepare and pg_execute functions). This will also save time
you are likely using to escape the inserted strings.



John DeSoi, Ph.D.
http://pgedit.com/
Power Tools for PostgreSQL