Received: from maia.hub.org (maia-5.hub.org [200.46.204.29]) by mail.postgresql.org (Postfix) with ESMTP id CFA8E1337B4B for ; Thu, 30 Sep 2010 16:16:46 -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 52026-07 for ; Thu, 30 Sep 2010 19:16:39 +0000 (UTC) X-Greylist: from auto-whitelisted by SQLgrey-1.7.6 Received: from sss.pgh.pa.us (sss.pgh.pa.us [66.207.139.130]) by mail.postgresql.org (Postfix) with ESMTP id 9A13D1337B4A for ; Thu, 30 Sep 2010 16:16:37 -0300 (ADT) Received: from sss2.sss.pgh.pa.us (tgl@localhost [127.0.0.1]) by sss.pgh.pa.us (8.14.2/8.14.2) with ESMTP id o8UJGa8w011341; Thu, 30 Sep 2010 15:16:37 -0400 (EDT) To: Marcelo Zabani cc: pgsql-performance@postgresql.org Subject: Re: gist indexes for distance calculations In-reply-to: References: Comments: In-reply-to Marcelo Zabani message dated "Thu, 30 Sep 2010 15:33:03 -0300" Date: Thu, 30 Sep 2010 15:16:36 -0400 Message-ID: <11340.1285874196@sss.pgh.pa.us> From: Tom Lane X-Virus-Scanned: Maia Mailguard 1.0.1 X-Spam-Status: No, hits=-1.91 tagged_above=-10 required=5 tests=BAYES_00=-1.9, T_RP_MATCHES_RCVD=-0.01 X-Spam-Level: X-Archive-Number: 201009/214 X-Sequence-Number: 40417 Marcelo Zabani writes: > CREATE INDEX ON places USING gist (circle(coordinates, 1)); > I'd like to know how this index works, though, as it seems to me the only > way to have this kind of index to work is to calculate the distance of every > point in a square of sides 2*1=2 units centered on (a, b). I believe it is a bounding-box based implementation; that is, each non-leaf entry in the index stores the bounding box that covers all the entries in the child page (plus its children if any). So a lookup descends to only those child pages that could possibly contain entries overlapping the target circle. > So, am I wrong to think it works like that? If it does work like that, could > I have instead two columns of type FLOAT (xcoordinate and ycoordinate) and > create traditional b-tree indexes on both of these, and then do something > like: > SELECT * FROM places WHERE xcoordinate >= (a-1) AND xcoordinate <= (a+1) AND > ycoordinate >= (b-1) AND ycoordinate <= (b+1) And > SQRT(POW(a-xcoordinate,2)+POW(b-ycoordinate,2))<=1; Well, there's nothing stopping you from doing that, but search performance is likely to be a whole lot worse than with an actual 2-D index. The reason is that it'll have to fetch index entries for everything in the vertical strip between a-1 and a+1, as well as everything in the horizontal strip between b-1 and b+1; most of which is nowhere near the target. If your circles are always very very small this might work tolerably, but in most applications the amount of stuff fetched soon gets out of hand. regards, tom lane