Received: from maia.hub.org (unknown [200.46.204.183]) by mail.postgresql.org (Postfix) with ESMTP id 0E745635CB7 for ; Thu, 30 Jul 2009 12:16:52 -0300 (ADT) Received: from mail.postgresql.org ([200.46.204.86]) by maia.hub.org (mx1.hub.org [200.46.204.183]) (amavisd-maia, port 10024) with ESMTP id 55747-01-5 for ; Thu, 30 Jul 2009 15:16:41 +0000 (UTC) X-Greylist: from auto-whitelisted by SQLgrey-1.7.6 Received: from out02.mta.xmission.com (out02.mta.xmission.com [166.70.13.232]) by mail.postgresql.org (Postfix) with ESMTP id 2B554635A70 for ; Thu, 30 Jul 2009 12:16:38 -0300 (ADT) Received: from in02.mta.xmission.com ([166.70.13.52]) by out02.mta.xmission.com with esmtp (Exim 4.62) (envelope-from ) id 1MWXMz-0007ic-9M; Thu, 30 Jul 2009 09:16:37 -0600 Received: from [208.187.158.94] (helo=[172.16.1.29]) by in02.mta.xmission.com with esmtpsa (TLSv1:AES256-SHA:256) (Exim 4.69) (envelope-from ) id 1MWXMy-0001Sb-Q1; Thu, 30 Jul 2009 09:16:37 -0600 Message-ID: <4A71B953.4070208@gmail.com> Date: Thu, 30 Jul 2009 09:16:35 -0600 From: Rob Sargent User-Agent: Thunderbird 2.0.0.22 (X11/20090608) MIME-Version: 1.0 To: wkipjohn@gmail.com CC: pgsql-sql@postgresql.org References: <0016e64f68205aab0d046fe35882@google.com> In-Reply-To: <0016e64f68205aab0d046fe35882@google.com> Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit X-XM-SPF: eid=; ; ; mid=; ; ; hst=in02.mta.xmission.com; ; ; ip=208.187.158.94; ; ; frm=robjsargent@gmail.com; ; ; spf=neutral X-SA-Exim-Connect-IP: 208.187.158.94 X-SA-Exim-Rcpt-To: wkipjohn@gmail.com, pgsql-sql@postgresql.org, robjsargent@gmail.com X-SA-Exim-Mail-From: robjsargent@gmail.com X-Spam-DCC: XMission; sa04 1397; Body=1 Fuz1=1 Fuz2=1 X-Spam-Combo: ;wkipjohn@gmail.com X-Spam-Relay-Country: Subject: Re: SQL report X-SA-Exim-Version: 4.2.1 (built Thu, 25 Oct 2007 00:26:12 +0000) X-SA-Exim-Scanned: Yes (on in02.mta.xmission.com) X-Virus-Scanned: Maia Mailguard 1.0.1 X-Spam-Status: No, hits=0 tagged_above=-10 required=5 tests=none X-Spam-Level: X-Archive-Number: 200907/152 X-Sequence-Number: 32893 I would be curious to know the performance curve for let's say 20K, 40K , 60K, 80K, 100K records. And what sort of indexing you have, whether or not it's clustered, re-built and so on. One could envision partitioning the status table such that recent records were grouped together (on the assumption that they will be most frequently "reported"). wkipjohn@gmail.com wrote: > I have the following senario. > > I have a tracking system. The system will record the status of an > object regularly, all the status records are stored in one table. And > it will keep a history of maximum 1000 status record for each object > it tracks. The maximum objects the system will track is 100,000. Which > means I will potentially have a table size of 100 million records. > > I have to generate a report on the latest status of all objects being > tracked at a particular point in time, and also I have to allow user > to sort and filter on different columes in the status record displayed > in the report. > > The following is a brief description in the status record (they are > not actual code) > > ObjectRecord( > objectId bigint PrimaryKey > desc varchar > ) > > StatusRecord ( > id bigint PrimaryKey > objectId bigint indexed > datetime bigint indexed > capacity double > reliability double > efficiency double > ) > > I have tried to do the following, it works very well with around > 20,000 objects. (The query return in less than 10s) But when I have > 100,000 objects it becomes very very slow. (I don't even have patience > to wait for it to return.... I kill it after 30 mins) > > select * from statusrecord s1 INNER JOIN ( SELECT objectId , > MAX(datetime) AS msdt FROM statusrecord WHERE startDatetime <= > 1233897527657 GROUP BY objectId ) AS s2 ON ( s1.objectId = s2.objectId > AND s1.datetime = s2.msdt ) where ( capacity < 10.0 ) order by > s1.datetime DESC, s1.objectId DESC; > > I did try to write a store procedure like below, for 100,000 objects > and 1000 status records / object, it returns in around 30 mins. > > CREATE OR REPLACE FUNCTION getStatus(pitvalue BIGINT) RETURNS SETOF > statusrecord AS $BODY$ > DECLARE > id VARCHAR; > status statusrecord%ROWTYPE; > BEGIN > FOR object IN SELECT * FROM objectRecord > LOOP > EXECUTE 'SELECT * FROM statusrecord WHERE objectId = ' || > quote_literal(object.objectId) || > ' AND datetime <= ' || quote_literal(pitvalue) || ' ORDER BY datetime > DESC' > INTO status; > IF FOUND THEN > RETURN NEXT status; > END IF; > END LOOP; > RETURN; > END > $BODY$ LANGUAGE plpgsql; > > Just wanna to know if anyone have a different approach to my senario. > Thanks alot. > > John