Received: from maia.hub.org (maia-5.hub.org [200.46.204.29]) by mail.postgresql.org (Postfix) with ESMTP id EE8E2B5D944 for ; Wed, 3 Aug 2011 22:55:44 -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 26595-10 for ; Thu, 4 Aug 2011 01:55:39 +0000 (UTC) Received: from news.hub.org (news.hub.org [200.46.204.72]) by mail.postgresql.org (Postfix) with ESMTP id E6506B5D80A for ; Wed, 3 Aug 2011 22:55:38 -0300 (ADT) Received: from news.hub.org (news.hub.org [200.46.204.72]) by news.hub.org (8.14.4/8.14.4) with ESMTP id p741tbxB066856 for ; Wed, 3 Aug 2011 22:55:37 -0300 (ADT) (envelope-from news@news.hub.org) Received: (from news@localhost) by news.hub.org (8.14.4/8.14.4/Submit) id p741rKK1060700 for pgsql-performance@postgresql.org; Wed, 3 Aug 2011 22:53:20 -0300 (ADT) (envelope-from news) From: Clem Dickey X-Newsgroups: pgsql.performance Subject: Re: Re: GROUP BY with reasonable timings in PLAN but unreasonable execution time Date: Wed, 03 Aug 2011 18:53:19 -0700 Organization: Hub.Org Networking Services Lines: 64 Message-ID: References: Mime-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit X-Complaints-To: usenet@news.hub.org User-Agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.18) Gecko/20110621 Fedora/3.1.11-1.fc14 Thunderbird/3.1.11 In-Reply-To: To: pgsql-performance@postgresql.org X-Virus-Scanned: Maia Mailguard 1.0.1 X-Spam-Status: No, hits=-2.616 tagged_above=-10 required=5 tests=BAYES_00=-1.9, RP_MATCHES_RCVD=-0.716 X-Spam-Level: X-Archive-Number: 201108/73 X-Sequence-Number: 44520 On 08/03/2011 06:29 AM, Robert Haas wrote: >> b. the Merge Join cost estimator did a poor job with the data it was given: >> >> In function eqjoinsel_inner there are two cases (1) ANALYZE data is >> available for both sides of the join and (2) ANALYZE data is missing for one >> or both sides. Due to the GROUP BY processing described above, ANALYZE data >> was available for "t" but not for "SELECT * FROM t GROUP BY ...". >> >> The logic in that case is "use the column with the most distinct values" to >> estimate selectivity. The default number of distinct values for a column >> with no data (DEFAULT_NUM_DISTINCT) is 200. In my join the number of values >> was: >> >> col in GROUP BY in table t >> j 200 1 >> k 200 1 >> x 200 10 >> y 200 1000 >> z 200 30 >> >> In 4 of the 5 columns the default value had more distinct values, and the >> combined selectivity (chance that two arbitrary rows would have a join >> match) was (1/200)^4 * 1/1000. Very small. The error is, IMO, that the code >> does not distinguish known numbers from default numbers. A comment in the >> code acknowledges this: > > I'm not sure I understand what you're getting at here, unless the idea > is to make get_variable_numdistinct() somehow indicate to the caller > whether it had to punt. That might be worth doing. Yes, the first step is to make "punt" a separate indicator. The second would be to make good use of that indicator. As it is now, with "punt" being a possible data value, there two types of errors: False negative (code treats DEFAULT_NUM_DISTINCT as ordinary case when it is special): I wanted eqjoinsel_inner() to treat "punt" specially: to use the value from the known side of the JOIN when the other side is unknown. The current behavior, although not ideal, is the expected use of a default value. False positive (code treats DEFAULT_NUM_DISTINCT as special case when it is ordinary): eqjoinsel_semi() and estimate_hash_bucketsize() treat DEFAULT_NUM_DISTINCT specially. This behavior is less defensible than false positive, since a valid numeric value is being re-used as a flag. I suggest wrapping the value in a struct (to avoid accidental use) and using macros for read access. typedef struct { double value; // negative means "unknown" } num_distinct_t; #define IS_NUM_DISTINCT_DEFINED(nd) ((nd).value >= 0) #define NUM_DISTINCT_VALUE(nd) ((nd).value) - Clem Dickey P.S. Congratulations on displacing MySQL in Mac OS X Lion Server.