Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtp (Exim 4.80) (envelope-from ) id 1abWFB-0002Ip-4a for pgsql-hackers@arkaria.postgresql.org; Thu, 03 Mar 2016 16:36:53 +0000 Received: from localhost ([127.0.0.1] helo=postgresql.org) by malur.postgresql.org with smtp (Exim 4.84) (envelope-from ) id 1abWFA-0007X3-In for pgsql-hackers@arkaria.postgresql.org; Thu, 03 Mar 2016 16:36:52 +0000 Received: from makus.postgresql.org ([2001:4800:1501:1::229]) by malur.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA384:256) (Exim 4.84) (envelope-from ) id 1abWDo-0004dh-6F for pgsql-hackers@postgresql.org; Thu, 03 Mar 2016 16:35:28 +0000 Received: from mail-wm0-x22b.google.com ([2a00:1450:400c:c09::22b]) by makus.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.84) (envelope-from ) id 1abWDg-0007vP-Vx for pgsql-hackers@postgresql.org; Thu, 03 Mar 2016 16:35:26 +0000 Received: by mail-wm0-x22b.google.com with SMTP id n186so139710377wmn.1 for ; Thu, 03 Mar 2016 08:35:20 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=2ndquadrant-com.20150623.gappssmtp.com; s=20150623; h=subject:to:references:cc:from:message-id:date:user-agent :mime-version:in-reply-to:content-transfer-encoding; bh=FBvfbcrE6iLTi2ifKh9Wyimu1LJIR7jtLFcDFpJQF/A=; b=M6zg6BXm83pRt4vlv9HBM/savZLPBxgWIORxDAQ18Kc0G8RA0gnidY3hc/F37GZNcM LQfnlqEkLnVN1Fhq5Whgyf/WVnXvOM2lWnWxl2twiNXyYI3VzvZDOThOjLd+aH91+4gt d6KNOqUwwiZm6rRwPc1fN9NF3kUZ1pFfTYah7Qi3CQXzq/wVmXc2A5DMjhCmnQbZzfVT a28jlkwLvdlhOoICAZZ+jq9r4Otb8fBoqU/fuvYAHOP6kSJRHn/6vwD6aaVVLZ5r6MIr 5vsA/oTl5EGU22x+mpwD107DIsz7sKF7IjI3hycTcuTXOU4Ubmfu/Y2+TOhzCbris13A PC3Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:subject:to:references:cc:from:message-id:date :user-agent:mime-version:in-reply-to:content-transfer-encoding; bh=FBvfbcrE6iLTi2ifKh9Wyimu1LJIR7jtLFcDFpJQF/A=; b=cQt8Dq86TV/23G3vlDivo2nRiJqCEr6jCF8EHEt8RxzYLqSRy4x2vszzCq37j0MCPk oJa1X1TJMVwRruHh/X9DdZWcrMI2/QAwVcIOdZ4XIHgo6MtlukVwkEkfaXwGVsrF6dWn IOJVaMorSAijcQOKWLLcApnmIUxkwfTKUrxFH7hYoguwdNwEeCbHp8aCrk3jLgSKAFGE fj55OpijWl0Fahg1XTk+YGG9EMxKEqDV/lVbj4teqsHjybyJ7Ke4otWkeTaMAM9tal5g UK258FvLczh+tLjMs1864MCpjfHDSyejt/Ylza2mS1PuLYnzicPwGLCtTZNjGJ72b/SC kTlg== X-Gm-Message-State: AD7BkJJ1mK2D9eQICehjmadqZtJOXVOfhMVxHCWZtJa8YCVjwmo7N7K17g5lwXomuOM6CycNs1m9aiPNzgMA/shqd0oU3+JosygJHBGQHeeADzvZOubHii6FEebDRonjbXg/RyiisqZXFj/2TUVlGBg/dlpYw9fRRb637DgZ9hYyNObtinWIm6lB8mvQI6YYYWUP4LhN8iaS X-Received: by 10.28.11.131 with SMTP id 125mr7175856wml.58.1457022919000; Thu, 03 Mar 2016 08:35:19 -0800 (PST) Received: from [10.137.1.13] (ip-78-45-216-26.net.upcbroadband.cz. [78.45.216.26]) by smtp.gmail.com with ESMTPSA id n131sm9662129wmf.9.2016.03.03.08.35.17 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 03 Mar 2016 08:35:18 -0800 (PST) Subject: Re: improving GROUP BY estimation To: Alexander Korotkov References: <56CD0381.5060502@2ndquadrant.com> <03A3B58D-6A2D-44FE-9B03-E21948CFCBAA@gmail.com> <56CFA373.3060105@2ndquadrant.com> <7D1A65E8-7ED8-4268-9C24-8EA07E95D2BC@gmail.com> <56CFCE96.5080306@2ndquadrant.com> Cc: Mark Dilger , PostgreSQL-development From: Tomas Vondra Message-ID: <56D867C3.3040309@2ndquadrant.com> Date: Thu, 3 Mar 2016 17:35:15 +0100 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Thunderbird/38.1.0 MIME-Version: 1.0 In-Reply-To: Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 7bit X-Pg-Spam-Score: -2.6 (--) List-Archive: List-Help: List-ID: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: X-Mailing-List: pgsql-hackers Precedence: bulk Sender: pgsql-hackers-owner@postgresql.org Hi, On 03/03/2016 12:53 PM, Alexander Korotkov wrote: > Hi, Tomas! > > I've assigned to review this patch. > > I've checked version estimate-num-groups-v2.txt by Mark Dilger. > It applies to head cleanly, passes corrected regression tests. > > About correlated/uncorrelated cases. I think now optimizer mostly assumes > all distributions to be independent. I think we should follow this > assumption in this case also until we have fundamentally better option (like > your multivariate statistics). > > @@ -3438,9 +3438,9 @@ estimate_num_groups(PlannerInfo *root, List *groupExprs, > double input_rows, > reldistinct = clamp; > > /* > -* Multiply by restriction selectivity. > +* Estimate number of distinct values expected in given number of rows. > */ > -reldistinct *= rel->rows / rel->tuples; > +reldistinct *= (1 - powl((reldistinct - 1) / reldistinct, rel->rows)); > > /* > * Update estimate of total distinct groups. > > I think we need way more explanation in comments here (possibly with > external links). For now, it looks like formula which appears from nowhere. I thought the details (particularly the link to stackexchange, discussing the formula) would be enough, but let me elaborate. The current formula reldistinct *= rel->rows / rel->tuples; simply multiplies the ndistinct estimate with selectivity. So when you select 1% of the table, the estimate says we'll see 1% of ndistinct values. But clearly that's naive, because for example when you have 10k distinct values and you select 10M rows, you should expect nearly all of them in the sample. And that's what the formula does - it gives you the expected number of distinct values, when selecting 'k' values from 'd' distinct values with replacements: count(k, d) = d * (1 - ((d-1)/d) ^ k) It's assuming the distinct values are equally probable (uniform distribution) and that the probabilities do not change (that's the "with replacement"). I guess we could relax those assumptions and for example use the MCV statistics to further improve the estimate, and also relax the 'with replacement' but that'd make the formula way more complicated. [1] http://math.stackexchange.com/questions/72223/finding-expected-number-of-distinct-values-selected-from-a-set-of-integers > > Also, note that rel->tuples gone away from formula parameters. So, we > actually don't care about how may tuples are in the table. This is because > this formula assumes that same tuple could be selected multiple times. For > low numbers this can lead to some errors. Consider selecting 2 from 3 > distinct tuples. If you can't select same tuple twice then you always > selecting 2 distinct tuples. But according to formula you will select 5/3 in > average. I think this error in small numbers is negligible, especially > because getting rid of this error would require way more computations. But > it worth mentioning in comments though. Well, yeah. That's the consequence of 'with replacement' assumption. I guess we could handle this somehow, though. For example we can compute the minimum possible number of distinct values like this: average_rows_per_value = (tuples / ndistinct); min_estimate = ceil(rows / average_rows_per_value); and use that as a minimum for the estimate. In the example you've given this would say average_rows_per_value = (3 / 3) = 1; min_estimate = ceil(2 / 1) = 2; So it serves as a correction for the 'with replacement' assumption. With only 2 distinct values we'd get this: average_rows_per_value = (3 / 2) = 1.5; min_estimate = ceil(2 / 1.5) = 2; Of course, it's just a heuristics, so this may fail in some other cases. regards -- Tomas Vondra http://www.2ndQuadrant.com PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services -- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers