From: | Melanie Plageman <melanieplageman(at)gmail(dot)com> |
---|---|
To: | Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us> |
Cc: | PostgreSQL Hackers <pgsql-hackers(at)lists(dot)postgresql(dot)org> |
Subject: | Re: BUG #15160: planner overestimates number of rows in join when there are more than 200 rows coming from CTE |
Date: | 2018-11-16 18:31:47 |
Message-ID: | CAAKRu_Y+d3SKkofNK7znhwgLauPUCVyZU=H0mvJH1LG7+tMyXg@mail.gmail.com |
Views: | Raw Message | Whole Thread | Download mbox | Resend email |
Thread: | |
Lists: | pgsql-bugs pgsql-hackers |
Thanks for the quick responses. I've put some inline follow-up questions.
On a separate note, I had one additional code clarity feedback. I felt that
eqjoinsel could be reorganized a bit for readability/clarity for the reader.
For example, eqjoinsel_inner uses only the AttStatsSlots up until here and
then
suddenly uses the original stats object and the ndvs which we passed in:
else
{
...
double nullfrac1 = stats1 ? stats1->stanullfrac : 0.0;
double nullfrac2 = stats2 ? stats2->stanullfrac : 0.0;
selec = (1.0 - nullfrac1) * (1.0 - nullfrac2);
if (nd1 > nd2)
selec /= nd1;
else
selec /= nd2;
}
It would make the process of calculating selectivity for an equijoin more
clear
to the reader if the nullfraction calculation was pulled out into the main
eqjoinsel function.
Having a clear set of steps in eqjoinsel would be helpful. Basically, my
understanding of an overview of the steps is the following:
1) get NDVs
2) get nullfrac
3) get MCVs
4) calculate selectivity
Based on this assumption, I've attached a patch with a rough idea for an
alternative structure that I think would be more clear to the reader.
> > I could not devise an example in which the previous method of calculating
> > selectivity would have produced a better estimate. However, one question
> I have
> > after thinking through the optimization is the following:
> > ...
> > To summarize:
> > Selectivity Type | if nd1 <= nd2 | if nd1 > nd2 |
> > ----------------------------------|----------------|-----------------
> > inner-join selectivity * ntuples2 | ntuples2 / nd2 | ntuples2 / nd1 |
> > semi-join selectivity | 1 | nd2 / nd1 |
>
> Um, mumble. Those functions could be using different values of nd2
> thanks to the clamping logic near the head of eqjoinsel_semi, so I'm
> not sure that the comparison you're making really holds.
>
That's a good point. Taking another look at that clamping logic, I realized
that I don't really understand why that clamping would be done for a
semi-join
and not for an inner join. It seems like for an inner join it is also true
that
the the nd1 cannot be greater than outer rel estimated tuples and nd2 could
not
be greater than inner rel estimated tuples.
Also, I don't understand when vardata2->rel->rows and inner_rel->rows would
be
different. I thought the point of doing this clamping was that, if you have
a
restriction, like the predicate in this subquery select * from foo where a
in
(select b from bar where b > 10); your row estimate for bar and your row
estimate for the rows out for that subquery would be different. However, I
looked at the RelOptInfos for vardata2->rel and inner_rel for this query
and it
seems like they are referencing the same relation and have the same rows
estimate, so I'm confused when the rows would be different.
> If there is a reason to keep the existing formula, then I have an
> additional
> > question about the proposed selectivity calculation:
> > selec = Min(selec, nd2 * selec_inner);
> > When would it be incorrect to instead multiply by inner side NDVs?
>
> I'm confused ... isn't that exactly what this is doing?
>
Sorry, typo, I was asking why
selec = Min(selec, nd2 * selec_inner);
could not be used instead of what is in the patch
selec = Min(selec, inner_rel->rows * selec_inner);
Thanks,
Melanie
Attachment | Content-Type | Size |
---|---|---|
suggested_semijoin_selec_refactor.patch | application/octet-stream | 6.4 KB |
From | Date | Subject | |
---|---|---|---|
Next Message | Tom Lane | 2018-11-16 22:33:17 | Re: BUG #15449: file_fdw using program cause exit code error when using LIMIT |
Previous Message | Tom Lane | 2018-11-16 17:33:51 | Re: BUG #15449: file_fdw using program cause exit code error when using LIMIT |
From | Date | Subject | |
---|---|---|---|
Next Message | Tom Lane | 2018-11-16 18:35:15 | Re: Problem while updating a foreign table pointing to a partitioned table on foreign server |
Previous Message | Alvaro Herrera | 2018-11-16 18:31:18 | Re: Constraint documentation |