Received: from localhost (unknown [200.46.204.183]) by developer.postgresql.org (Postfix) with ESMTP id 938A32E0067 for ; Thu, 10 Apr 2008 18:33:44 -0300 (ADT) Received: from developer.postgresql.org ([200.46.204.71]) by localhost (mx1.hub.org [200.46.204.183]) (amavisd-maia, port 10024) with ESMTP id 81601-05 for ; Thu, 10 Apr 2008 18:33:41 -0300 (ADT) X-Greylist: from auto-whitelisted by SQLgrey-1.7.5 Received: from h07.llord.com (unknown [195.140.142.194]) by developer.postgresql.org (Postfix) with ESMTP id B36262E006A for ; Thu, 10 Apr 2008 18:33:41 -0300 (ADT) Received: from par69-8-88-161-102-87.fbx.proxad.net ([88.161.102.87] helo=apollo13.peufeu.com) by h07.llord.com with esmtpa (Exim 4.68) (envelope-from ) id 1Jk4Om-0008Md-Bm; Thu, 10 Apr 2008 23:33:36 +0200 Date: Thu, 10 Apr 2008 23:37:50 +0200 To: "John Beaver" , Matthew Subject: Re: large tables and simple "= constant" queries using indexes From: PFC Cc: Pgsql-Performance Content-Type: text/plain; format=flowed; delsp=yes; charset=utf-8 MIME-Version: 1.0 References: <47FD2DF3.80500@gmail.com> <47FD3350.4060504@tweakers.net> <47FD4212.8040404@gmail.com> <47FDBE23.8020402@tweakers.net> <47FE27EB.8050804@gmail.com> Content-Transfer-Encoding: Quoted-Printable Message-ID: In-Reply-To: <47FE27EB.8050804@gmail.com> User-Agent: Opera Mail/9.24 (Linux) X-AntiAbuse: This header was added to track abuse, please include it with any abuse report X-AntiAbuse: Primary Hostname - h07.llord.com X-AntiAbuse: Original Domain - postgresql.org X-AntiAbuse: Originator/Caller UID/GID - [47 12] / [47 12] X-AntiAbuse: Sender Address Domain - peufeu.com X-Source: X-Source-Args: X-Source-Dir: X-Virus-Scanned: Maia Mailguard 1.0.1 X-Spam-Status: No, hits=0.925 tagged_above=0 required=5 tests=AWL=0.825, RDNS_NONE=0.1 X-Spam-Level: X-Archive-Number: 200804/138 X-Sequence-Number: 29631 > Thanks a lot, all of you - this is excellent advice. With the data = > clustered and statistics at a more reasonable value of 100, it now = > reproducibly takes even less time - 20-57 ms per query. 1000x speedup with proper tuning - always impressive, lol. IO seeks are always your worst enemy. > After reading the section on "Statistics Used By the Planner" in the = > manual, I was a little concerned that, while the statistics sped up th= e = > queries that I tried immeasurably, that the most_common_vals array was= = > where the speedup was happening, and that the values which wouldn't fi= t = > in this array wouldn't be sped up. Though I couldn't offhand find an = > example where this occurred, the clustering approach seems intuitively= = > like a much more complete and scalable solution, at least for a = > read-only table like this. Actually, with statistics set to 100, then 100 values will be stored in= = most_common_vals. This would mean that the values not in most_common_val= s = will have less than 1% frequency, and probably much less than that. The = = choice of plan for these rare values is pretty simple. With two columns, "interesting" stuff can happen, like if you have col1= = in [1...10] and col2 in [1...10] and use a condition on col1=3Dconst and= = col2=3Dconst, the selectivity of the result depends not only on the = distribution of col1 and col2 but also their correlation. As for the tests you did, it's hard to say without seeing the explain = analyze outputs. If you change the stats and the plan choice (EXPLAIN) = stays the same, and you use the same values in your query, any differenc= e = in timing comes from caching, since postgres is executing the same plan = = and therefore doing the exact same thing. Caching (from PG and from the = = OS) can make the timings vary a lot. > - Trying the same constant a second time gave an instantaneous result,= = > I'm guessing because of query/result caching. PG does not cache queries or results. It caches data & index pages in i= ts = shared buffers, and then the OS adds another layer of the usual disk cac= he. A simple query like selecting one row based on PK takes about 60 = microseconds of CPU time, but if it needs one seek for the index and one= = for the data it may take 20 ms waiting for the moving parts to move... = Hence, CLUSTER is a very useful tool. Bitmap index scans love clustered tables because all the interesting ro= ws = end up being grouped together, so much less pages need to be visited. > - I didn't try decreasing the statistics back to 10 before I ran the = > cluster command, so I can't show the search times going up because of = = > that. But I tried killing the 500 meg process. The new process uses le= ss = > than 5 megs of ram, and still reproducibly returns a result in less th= an = > 60 ms. Again, this is with a statistics value of 100 and the data = > clustered by gene_prediction_view_gene_ref_key. Killing it or just restarting postgres ? If you let postgres run (not idle) for a while, naturally it will fill = = the RAM up to the shared_buffers setting that you specified in the = configuration file. This is good, since grabbing data from postgres' own= = cache is faster than having to make a syscall to the OS to get it from t= he = OS disk cache (or disk). This isn't bloat. But what those 500 MB versus 6 MB show is that before, postgres had to = = read a lot of data for your query, so it stayed in the cache ; after = tuning it needs to read much less data (thanks to CLUSTER) so the cache = = stays empty.