From: | "David G(dot) Johnston" <david(dot)g(dot)johnston(at)gmail(dot)com> |
---|---|
To: | Rafal Pietrak <rafal(at)ztk-rp(dot)eu> |
Cc: | "pgsql-general(at)lists(dot)postgresql(dot)org" <pgsql-general(at)lists(dot)postgresql(dot)org> |
Subject: | Re: FK v.s unique indexes |
Date: | 2018-07-05 21:55:48 |
Message-ID: | CAKFQuwa3fZf9m_nM4aXqU-BD-bS1b5FGmhmKnsjhzSShyVobuA@mail.gmail.com |
Views: | Raw Message | Whole Thread | Download mbox | Resend email |
Thread: | |
Lists: | pgsql-general |
On Thu, Jul 5, 2018 at 2:36 PM, Rafal Pietrak <rafal(at)ztk-rp(dot)eu> wrote:
>
>
> W dniu 05.07.2018 o 23:04, David G. Johnston pisze:
> > On Thu, Jul 5, 2018 at 1:45 PM, Rafal Pietrak <rafal(at)ztk-rp(dot)eu
> > <mailto:rafal(at)ztk-rp(dot)eu>>wrote:
> >
> > I was thinking, that when "add constraint" cannot choose appropriate
> > index, may be some explicit help (like ... using <index_name>;)
> would be
> > due.
> >
> >
> > Basically all the FK trigger does is:
> >
> > SELECT EXISTS(SELECT 1 FROM pk_table WHERE pk_col1 = val1 AND pk_col2 =
> > val2)
> >
> > And fails if query returns false. The planner is still free to use the
> > index or not to execute the query just as if you had written it by
> > hand. For a small table fully in memory it likely would prefer a
> > sequential scan and it would be perfectly within its rights to do so.
> >
>
> I must assume, that the above "WHERE pk_col1 - val1..." is not the same
> place as the one you've mentioned earlier, where "FK don't have where
> clausures".
>
The FK definition doesn't have a WHERE clause so the only (and all)
columns used in the trigger are those defined by the constraint itself.
So, if a partial index for the above was:
UNIQUE INDEX (pk_col1, pk_col2) WHERE pktblcol3 = false;
and
FK (col1, col2) REFERENCES pk_table (pk_col1, pk_col2)
There is no place on the FK to reference "pktblcol3" so that the
effective trigger query would become:
WHERE pk_col1 = val2 AND pk_col2 = val2 AND pktblcol3 = ???
And without pktblcol3 more than one row could be returned (so, not really
EXISTS...)
>
> Thus, the bulk of code that maintains FK consistency "does not use where
> clausures", would break on partial indexes. But in the above SELECT,
> with partial indexed, that select will never fail. So it is not the
> blocker... on the other hand, I would rather rewrite it along the lines of:
> SELECT 1 = (SELECT count(1) FROM pk_table WHERE pk_col1 = val1 AND
> pk_col2 = val2)
>
Yeah, that's closer to reality
>
> Naturally, if the planner choses to do a seq scan, everything would
> break down - inappropriate rows would get hit; but that's a different
> story:
> 1. one may think, doing a "SELECT * FROM pk_table WHERE... INTO current"
> and making all constraint trigger functions use that "current" instead
> of making more lookups, could solve the problem.
> 2. or with some syntax help during FK creation (aka: ... add constraint
> ... using <index_name>) one could force the planner to always use
> indicated index.
>
This comes back to constraints don't directly target indexes even though
indexes are used in implementation (it would be violation of scope). They
target other constraints at a logical level. Whether the code is written
exactly like that without evidence to the contrary it provides a sound
mental model to operate from.
I think we might get away from this for INSERT ON CONFLICT but I'm not that
well versed nor have time to look into it right now.
David J.
From | Date | Subject | |
---|---|---|---|
Next Message | Paul A Jungwirth | 2018-07-05 23:44:39 | User-defined function with anyrange[] |
Previous Message | Rafal Pietrak | 2018-07-05 21:36:45 | Re: FK v.s unique indexes |