Received: from localhost (maia-2.hub.org [200.46.204.187]) by postgresql.org (Postfix) with ESMTP id 07D629FB21C for ; Sun, 14 Jan 2007 15:20:49 -0400 (AST) Received: from postgresql.org ([200.46.204.71]) by localhost (mx1.hub.org [200.46.204.187]) (amavisd-new, port 10024) with ESMTP id 98418-04 for ; Sun, 14 Jan 2007 15:20:34 -0400 (AST) X-Greylist: from auto-whitelisted by SQLgrey-1.7.4 Received: from exprod6og55.obsmtp.com (exprod6og55.obsmtp.com [64.18.1.191]) by postgresql.org (Postfix) with SMTP id C6BA29FB219 for ; Sun, 14 Jan 2007 15:20:47 -0400 (AST) Received: from source ([63.240.6.47]) (using TLSv1) by exprod6ob55.postini.com ([64.18.5.12]) with SMTP; Sun, 14 Jan 2007 11:20:45 PST Received: from 172.16.1.239 by mail.Mi8.com with ESMTP (- Welcome to Mi8 Corporation www.Mi8.com (D1)); Sun, 14 Jan 2007 14:20:39 -0500 X-Server-Uuid: 241911D6-425B-44B9-A073-E3FE0F8FC774 Received: from MI8NYCMAIL08.Mi8.com ([172.16.1.164]) by d01smtp06.Mi8.com with Microsoft SMTPSVC(6.0.3790.1830); Sun, 14 Jan 2007 14:20:38 -0500 Received: from 69.181.100.71 ([69.181.100.71]) by MI8NYCMAIL08.Mi8.com ( [172.16.1.190]) via Exchange Front-End Server mi8owa.mi8.com ( [172.16.1.106]) with Microsoft Exchange Server HTTP-DAV ; Sun, 14 Jan 2007 19:20:38 +0000 User-Agent: Microsoft-Entourage/11.3.2.061213 Date: Sun, 14 Jan 2007 11:20:35 -0800 Subject: Re: Large table performance From: "Luke Lonergan" To: "Mark Dobbrow" , pgsql-performance@postgresql.org Message-ID: Thread-Topic: [PERFORM] Large table performance Thread-Index: Acc4ERDATzwxj6QEEdu0xAAWy4o9DA== In-Reply-To: <376735.48483.qm@web35309.mail.mud.yahoo.com> MIME-Version: 1.0 X-OriginalArrivalTime: 14 Jan 2007 19:20:38.0316 (UTC) FILETIME=[12BA7EC0:01C73811] X-WSS-ID: 69B45D0C2IS276073-03-01 Content-Type: multipart/alternative; boundary=B_3251618436_675815 X-Virus-Scanned: Maia Mailguard 1.0.1 X-Archive-Number: 200701/226 X-Sequence-Number: 22827 > This message is in MIME format. Since your mail reader does not understand this format, some or all of this message may not be legible. --B_3251618436_675815 Content-Type: text/plain; charset=iso-8859-1 Content-Transfer-Encoding: quoted-printable Mark, Note that selecting an index column means that Postgres fetches the whole rows from disk. I think your performance problem is either: 1) slow disk o= r 2) index access of distributed data. If it=B9s (1), there are plenty of references from this list on how to check for that and fix it. If it=B9s (2)= , see below.=20 The performance of index accessed data in Postgres depends on how the data is loaded into the DBMS. If the records you are fetching are distributed widely among the 3M records on disk, then the select is going to =B3hop, skip and jump=B2 across the disk to get the records you need. If those records ar= e stored more closely together, then the fetching from disk is going to be sequential. A good example of the best situation for an index is an index on a date column when the data is loaded sequentially by date. A query against a specific date range will result in an ordered fetch from the disk= , which leverages fast sequential access. The difference in performance between ordered and distributed access is similar to the difference between =B3random seek=B2 and =B3sequential=B2 performanc= e of the disk subsystem. The random seek performance of typical disk subsystems with one thread (for one user in postgres) is 120 seeks per second. If your data was randomly distributed, you=B9d expect about 10,000/120 =3D 83 seconds to gather these records. Since you=B9re getting 10 seconds, I expect that your data is lumped into groups and you are getting = a mix of sequential reads and seeks. Note that adding more disks into a RAID does not help the random seek performance within Postgres, but may linearly improve the ordered access speed. So even with 44 disks in a RAID10 pool on a Sun X4500, the seek performance of Postgres (and other DBMS=B9s without async or threaded I/O) is that of a single disk =AD 120 seeks per second. Adding more users allows the seeks to scale on such a machine as users are added, up to the number of disks in the RAID. But for your one user example =AD no help. If your problem is (2), you can re-order the data on disk by using a CREATE TABLE statement like this: CREATE TABLE fast_table AS SELECT * FROM slow_table ORDER BY teacher_id; CREATE INDEX teacher_id_ix ON fast_table; VACUUM ANALYZE fast_table; You should then see ordered access when you do index scans on teacher_id. - Luke On 1/12/07 4:31 PM, "Mark Dobbrow" wrote: > Hello -=20 >=20 > I have a fairly large table (3 million records), and am fetching 10,000 > non-contigous records doing a simple select on an indexed column ie >=20 > select grades from large_table where teacher_id =3D X >=20 > This is a test database, so the number of records is always 10,000 and i = have > 300 different teacher ids. >=20 > The problem is, sometimes fetching un-cached records takes 0.5 secs and > sometimes (more often) is takes more like 10.0 seconds >=20 > (fetching the same records for a given teacher_id a second time takes abo= ut > 0.25 secs) >=20 > Has anyone seen similar behavior or know what the solution might be? >=20 > any help much appreciated, > Mark >=20 >=20 >=20 > ps. My shared_buffers is set at 5000 (kernal max), and work_mem=3D8192 >=20 >=20 >=20 --B_3251618436_675815 Content-Type: text/html; charset=iso-8859-1 Content-Transfer-Encoding: quoted-printable Re: [PERFORM] Large table performance Mark,=

Note that selecting an index column means that Postgres fetches the whole r= ows from disk.  I think your performance problem is either: 1) slow dis= k or 2) index access of distributed data.  If it’s (1), there are= plenty of references from this list on how to check for that and fix it. &n= bsp;If it’s (2), see below.

The performance of index accessed data in Postgres depends on how the data = is loaded into the DBMS.  If the records you are fetching are distribut= ed widely among the 3M records on disk, then the select is going to “h= op, skip and jump” across the disk to get the records you need.  = If those records are stored more closely together, then the fetching from di= sk is going to be sequential.  A good example of the best situation for= an index is an index on a date column when the data is loaded sequentially = by date.  A query against a specific date range will result in an order= ed fetch from the disk, which leverages fast sequential access.

The difference in performance between ordered and distributed access is sim= ilar to the difference between “random seek” and “sequenti= al” performance of the disk subsystem.  The random seek performan= ce of typical disk subsystems with one thread (for one user in postgres) is = 120 seeks per second.  If your data was randomly distributed, you’= ;d expect about 10,000/120 =3D 83 seconds to gather these records.  Since= you’re getting 10 seconds, I expect that your data is lumped into gro= ups and you are getting a mix of sequential reads and seeks.

Note that adding more disks into a RAID does not help the random seek perfo= rmance within Postgres, but may linearly improve the ordered access speed. &= nbsp;So even with 44 disks in a RAID10 pool on a Sun X4500, the seek perform= ance of Postgres (and other DBMS’s without async or threaded I/O) is t= hat of a single disk – 120 seeks per second.  Adding more users a= llows the seeks to scale on such a machine as users are added, up to the num= ber of disks in the RAID.  But for your one user example – no hel= p.

If your problem is (2), you can re-order the data on disk by using a CREATE= TABLE statement like this:
  CREATE TABLE fast_table AS SELECT * FROM slow_table ORDER BY te= acher_id;
  CREATE INDEX teacher_id_ix ON fast_table;
  VACUUM ANALYZE fast_table;

You should then see ordered access when you do index scans on teacher_id.
- Luke


On 1/12/07 4:31 PM, "Mark Dobbrow" <mdobbrow@yahoo.com> wro= te:

Hello -

I have a fairly large table (3 million records), and am fetching 10,000 non= -contigous records doing a simple select on an indexed column ie

select grades from large_table where teacher_id =3D X

This is a test database, so the number of records is always 10,000 and i ha= ve 300 different teacher ids.

The problem is, sometimes fetching un-cached records takes 0.5 secs and som= etimes (more often) is takes more like 10.0 seconds

(fetching the same records for a given teacher_id a second time takes about= 0.25 secs)

Has anyone seen similar behavior or know what the solution might be?

any help much appreciated,
Mark



ps. My shared_buffers is set at 5000 (kernal max), and work_mem=3D8192




--B_3251618436_675815--