Thread: Re: [GENERAL] Getting value of SERIAL column after insert from libpq?

Re: [GENERAL] Getting value of SERIAL column after insert from libpq?

From
"Mark Alliban"
Date:
Thanks for the help, it works great!

However, there is a problem with performance.
I am moving from MySQL to Postgres, and to test performance I am inserting a
large row (30 fields) into a table from my C program. I am running this
program 50 times, and timing the results. The MySQL version of the program
took 0.75 seconds to execute 50 times, but the Postgres version takes 22-25
seconds. A similar test with a simple select takes 3.5 seconds on Postgres
but 0.8 on MySQL. Postgres undoubtably has more features and is better for
my app than MySQL, but are these performance values normal?

All my program does is read the query from a text file, open the database
connection, perform the query, output currval('seqence_name') or the query
results to a text file, and close the connection. This is how my app needs
to work.

Thanks,
Mark.

>> Hi,
>>
>> I have written a C program to insert a row into a table with a
>> SERIAL column.
>>
>> Is there a way of returning the inserted value for this column
>> to my program? I.e. if there are rows with the serial column
>> for 1,2,3,4 and 5, and I insert a row, my program needs to be
>> told "6" for the new serial. There may be many instances of the
>> program running simultaneously so I can't do a "select max..."
>> or "select last_value..." workaround because by the time the
>> select is done, there may have been other rows inserted so the
>> last_value would be wrong. Also the program needs to be table-name
>> and column-name independent so that it can work for ANY insert
>> query into a table with a SERIAL column.
>
>Answer is that currval('seqence_name') will return your last sequence
>number, even if another session has assigned a sequence number since
>your nextval() call.



Re: [GENERAL] Getting value of SERIAL column after insert from libpq?

From
Mike Mascari
Date:
Mark Alliban wrote:
>
> Thanks for the help, it works great!
>
> However, there is a problem with performance.
> I am moving from MySQL to Postgres, and to test performance I am inserting a
> large row (30 fields) into a table from my C program. I am running this
> program 50 times, and timing the results. The MySQL version of the program
> took 0.75 seconds to execute 50 times, but the Postgres version takes 22-25
> seconds. A similar test with a simple select takes 3.5 seconds on Postgres
> but 0.8 on MySQL. Postgres undoubtably has more features and is better for
> my app than MySQL, but are these performance values normal?
>
> All my program does is read the query from a text file, open the database
> connection, perform the query, output currval('seqence_name') or the query
> results to a text file, and close the connection. This is how my app needs
> to work.
>
> Thanks,
> Mark.

Are you running with fsync() disabled? That is the single
largest bottleneck for PostgreSQL performance and is
disabled by default in MySQL, except on NT (since NT has a
tendency to crash). You can disable fsync() with the
postmaster -o -F option, to pass the option to the backend.
See the postmaster and postgres man pages for more info.

Hope that helps,

Mike Mascari

Re: [GENERAL] Getting value of SERIAL column after insert from libpq?

From
Howie
Date:
On Wed, 22 Dec 1999, Mark Alliban wrote:

> Thanks for the help, it works great!
>
> However, there is a problem with performance.
> I am moving from MySQL to Postgres, and to test performance I am inserting a
> large row (30 fields) into a table from my C program. I am running this
> program 50 times, and timing the results. The MySQL version of the program
> took 0.75 seconds to execute 50 times, but the Postgres version takes 22-25
> seconds.

yeouch, that doesnt sound normal... especially seeing that ive been
inserting ~100 rows, doing a convert, cp'ing a file, _and_ checking for
referential integrity in ~40-45 seconds... and the app has the normal perl
overhead.

make sure you've turned fsync off ( -F opt to postmaster iirc ).

> A similar test with a simple select takes 3.5 seconds on Postgres
> but 0.8 on MySQL. Postgres undoubtably has more features and is better for
> my app than MySQL, but are these performance values normal?

depends on the select.  if its not hitting indexes ( doing a full table
scan ), things get slow.  try doing an explain of the query and make sure
you have indexes on most (if not all) of the columns in the WHERE clause.

> [SNIP]

---
Howie <caffeine@toodarkpark.org>   URL: http://www.toodarkpark.org
"I've learned that you cannot make someone love you.
 All you can do is stalk them and hope they panic and give in."


Re: [GENERAL] Getting value of SERIAL column after insert from libpq?

From
Charles Tassell
Date:
Someone else had a good idea with the fsync thing, but for the inserts, you
also might want to double-check that you are using a transaction, as that
speeds up transactions considerably.  To start a transaction use the SQL
command "BEGIN WORK;" and then use "COMMIT WORK;" after you have finished
your inserts.  I don't think you can do a select inside a transaction,
(although I've never tried) so you may have to open up a second connection
to the database and find the value your sequence was assigned by SELECTing
the oid returned instead of by using curval()  I believe instructions on
this are in the FAQ.  If not, drop me a lien and I'll look for the PHP3
code I use to do it, it should be fairly close to how you do it in C.

At 12:49 PM 12/22/99, Mark Alliban wrote:
>Thanks for the help, it works great!
>
>However, there is a problem with performance.
>I am moving from MySQL to Postgres, and to test performance I am inserting a
>large row (30 fields) into a table from my C program. I am running this
>program 50 times, and timing the results. The MySQL version of the program
>took 0.75 seconds to execute 50 times, but the Postgres version takes 22-25
>seconds. A similar test with a simple select takes 3.5 seconds on Postgres
>but 0.8 on MySQL. Postgres undoubtably has more features and is better for
>my app than MySQL, but are these performance values normal?
>
>All my program does is read the query from a text file, open the database
>connection, perform the query, output currval('seqence_name') or the query
>results to a text file, and close the connection. This is how my app needs
>to work.
>
>Thanks,
>Mark.
>
> >> Hi,
> >>
> >> I have written a C program to insert a row into a table with a
> >> SERIAL column.
> >>
> >> Is there a way of returning the inserted value for this column
> >> to my program? I.e. if there are rows with the serial column
> >> for 1,2,3,4 and 5, and I insert a row, my program needs to be
> >> told "6" for the new serial. There may be many instances of the
> >> program running simultaneously so I can't do a "select max..."
> >> or "select last_value..." workaround because by the time the
> >> select is done, there may have been other rows inserted so the
> >> last_value would be wrong. Also the program needs to be table-name
> >> and column-name independent so that it can work for ANY insert
> >> query into a table with a SERIAL column.
> >
> >Answer is that currval('seqence_name') will return your last sequence
> >number, even if another session has assigned a sequence number since
> >your nextval() call.
>
>
>
>************


[GENERAL] fsync performance impact

From
Ed Loehr
Date:
Thought some would like to see a little quatitative data on the impact of running
with the -F flag...

Test case:  Using psql via stdin to load 5,238 inserts of the following form:

    INSERT INTO exchange_rate
    ( from_currency_id, to_currency_id, rate, start_time)
    VALUES
    (150,164, 6.01500000, '09/04/1999');

Platform:  RH6.1, 2.2.12-20smp, dual P3 600Mhz, 1 Gb RAM, 3 10K rpm scsi drives
in software raid.

Without -F, it loaded in 228 seconds (~23 inserts/sec).
With -F, it loaded in 10 seconds (~524 inserts/sec).

2200% boost...

Remember this performance boost comes at the expense of increased risk of data
loss in the event of a system crash.

Cheers,
Ed Loehr