Received: from maia.hub.org (maia-5.hub.org [200.46.204.29]) by mail.postgresql.org (Postfix) with ESMTP id 1026C6328DF for ; Fri, 21 May 2010 15:49:37 -0300 (ADT) Received: from mail.postgresql.org ([200.46.204.86]) by maia.hub.org (mx1.hub.org [200.46.204.29]) (amavisd-maia, port 10024) with ESMTP id 14047-07 for ; Fri, 21 May 2010 18:49:29 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.7.6 Received: from mail-ew0-f224.google.com (mail-ew0-f224.google.com [209.85.219.224]) by mail.postgresql.org (Postfix) with ESMTP id 244436321EB for ; Fri, 21 May 2010 15:49:28 -0300 (ADT) Received: by ewy24 with SMTP id 24so270486ewy.34 for ; Fri, 21 May 2010 11:49:27 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:received:received:message-id:date:from :user-agent:mime-version:to:cc:subject:references:in-reply-to :content-type:content-transfer-encoding; bh=YRAlc9hvUsG2m9gvDgQ7oRq8mU5+cdbHfPKGsJH0KtU=; b=YSox18hQNGhGuJCLXjTxAgoWK6Q01KV0AE4BC2iDTF8ni8hIfA8gjaQa6nW5VxPnk4 A07kvv7VeGv/2PLqwrx3mObNAPSVRQnA9uT1C9NBVLf8pdVA3EjYdeMekfQrtagKv6um kYF7mfpqTuLcDTCsIumA7nmmq63rgwdH+QDfQ= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=message-id:date:from:user-agent:mime-version:to:cc:subject :references:in-reply-to:content-type:content-transfer-encoding; b=I1QFGxX3F44Ro1xEcnv2BNSw9npThLgCwlKOfDOZh8/LrFL+N+OC2HYHWKkVbcuN96 HWDIZFSV82TJcxzkqoZmz1TfPncBZEjPBJaAWBRbqUKBlU7a0uuSqu1E3zLOMC/DzY1b prVJg6iZ94nBKeMyALVK/pllfTLu2fmZDLj6w= Received: by 10.213.49.79 with SMTP id u15mr751614ebf.20.1274467767391; Fri, 21 May 2010 11:49:27 -0700 (PDT) Received: from [0.0.0.0] (5357DA75.cable.casema.nl [83.87.218.117]) by mx.google.com with ESMTPS id 16sm620538ewy.11.2010.05.21.11.49.26 (version=TLSv1/SSLv3 cipher=RC4-MD5); Fri, 21 May 2010 11:49:26 -0700 (PDT) Message-ID: <4BF6D5C0.2030902@gmail.com> Date: Fri, 21 May 2010 20:49:36 +0200 From: Yeb Havinga User-Agent: Thunderbird 2.0.0.24 (Windows/20100228) MIME-Version: 1.0 To: David Jarvis CC: Stephen Frost , Tom Lane , Thom Brown , pgsql-performance@postgresql.org Subject: Re: Optimize date query for large child tables: GiST or GIN? References: <7917.1274385834@sss.pgh.pa.us> <8132.1274386738@sss.pgh.pa.us> <20100520210106.GO21875@tamriel.snowman.net> <4BF64693.8050800@gmail.com> <4BF64830.4080902@gmail.com> In-Reply-To: Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit X-Virus-Scanned: Maia Mailguard 1.0.1 X-Spam-Status: No, hits=-0.001 tagged_above=-10 required=5 tests=BAYES_20=-0.001, RCVD_IN_DNSWL_NONE=-0.0001 X-Spam-Level: X-Archive-Number: 201005/144 X-Sequence-Number: 38728 David Jarvis wrote: > Hi, Yeb. > > This is starting to go back to the design I used with MySQL: > > * YEAR_REF - Has year and station > * MONTH_REF - Has month, category, and yea referencer > * MEASUREMENT - Has month reference, amount, and day > > Normalizing by date parts was fast. Partitioning the tables by year > won't do much good -- users will probably choose 1900 to 2009, > predominately. Ok, in that case it is a bad idea. > I thought about splitting the data by station by category, but that's > ~73000 tables. My understanding is that PostgreSQL uses files per > index, which would be messy at the OS level (Linux 2.6.31). Even by > station alone is 12139 tables, which might be tolerable for now, but > with an order of magnitude more stations on the distant horizon, it > will not scale. Yes, I've read a few times now that PG's partitioning doesn't scale beyond a few 100 partitions. > I also thought about splitting the data by station district by > category -- there are 79 districts, yielding 474 child tables, which > is ~575000 rows per child table. Most of the time I'd imagine only one > or two districts would be selected. (Again, hard to know exactly.) I agee with Matthew Wakeling in a different post: its probably wise to first see how fast things can get by using indexes. Only if that fails to be fast, partitioning might be an option. (Though sequentially scanning 0.5M rows is not cheap). I experimented a bit with a doy and year function. -- note: leap year fix must still be added create or replace function doy(timestamptz) RETURNS float8 as 'select extract(doy from $1);' language sql immutable strict; create or replace function year(timestamptz) RETURNS float8 as 'select extract(year from $1);' language sql immutable strict; \d parent Table "public.parent" Column | Type | Modifiers --------+--------------------------+----------- t | timestamp with time zone | y | smallint | Indexes: "doy_i" btree (doy(t)) "year_i" btree (year(t)) A plan like the following is probably what you want test=# explain select * from parent where doy(t) between 10 and 20 and year(t) between 1900 and 2009; QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Bitmap Heap Scan on parent (cost=9.95..14.97 rows=1 width=10) Recheck Cond: ((year(t) >= 1900::double precision) AND (year(t) <= 2009::double precision) AND (doy(t) >= 10::double precision) AND (doy(t) <= 20::double precision)) -> BitmapAnd (cost=9.95..9.95 rows=1 width=0) -> Bitmap Index Scan on year_i (cost=0.00..4.85 rows=10 width=0) Index Cond: ((year(t) >= 1900::double precision) AND (year(t) <= 2009::double precision)) -> Bitmap Index Scan on doy_i (cost=0.00..4.85 rows=10 width=0) Index Cond: ((doy(t) >= 10::double precision) AND (doy(t) <= 20::double precision)) (7 rows) regards, Yeb Havinga