Skip to content

Improve SQL generator by grouping "exists" statements better - #471

Merged
kofrezo merged 2 commits into
mainfrom
dk_group_exists_for_related_attrs
Sep 23, 2026
Merged

kofrezo merged 2 commits into
mainfrom
dk_group_exists_for_related_attrs

Conversation

@kofrezo

@kofrezo kofrezo commented Sep 22, 2026

Copy link
Copy Markdown
Contributor

This PR contains improvements to the sql_generator module to better group exists for related attributes allowing the
Postgres query planner to filter rows more efficient.

When an attribute is attached directly to some servertypes and inherited
by others through a related_via attribute, _real_condition_sql() built a
single EXISTS over the value table whose WHERE OR'ed the relation paths
together. Postgres can turn a correlated EXISTS with one path into a hash
semi join, but not one whose correlation to "server" is an OR of
alternatives: it fell back to a nested loop over every (server, sub)
pair and evaluated the inherited path as a sub plan for each of them.

Emit one EXISTS per path instead and OR them outside, each guarded by
its servertype test written first. The guard order matters: Postgres
reorders AND clauses by cost at the top level only, not inside the
branches of an OR, and otherwise evaluates left to right, so the cheap
test now short-circuits the EXISTS for servertypes that do not use that
path. Boolean-equivalent to the old form, since the guards do not depend
on the inner row and factor out of the existential.
An attribute inherited through a related_via attribute was filtered with
an EXISTS correlated to the outer server row. Postgres evaluated it once
per candidate server, re-finding the same matching rows every time and
then testing each (server, match) pair one by one.

Render each inherited path as "server.server_id IN (subquery)" with
nothing in the subquery referencing the outer server. Postgres then
evaluates it once, hashes the ids and probes per row, and for a supernet
path drives the containment join from the matching networks' prefixes,
which is what the GiST index exists for. Cost becomes (candidates +
matches) rather than their product. The directly attached path keeps its
correlated EXISTS, which Postgres already turns into a semi join (or an
anti join under NOT), so the SQL for attributes that are not inherited
anywhere is unchanged.

The selected column is a NOT NULL foreign key in every branch, so NOT IN
keeps set semantics: no NULL can make the test unknown.

_supernet_af_sql() factors the address-family joins out of
_supernet_exists_sql(), which still serves direct supernet filters and
ContainedOnlyBy and emits exactly what it did before.
@kofrezo
kofrezo requested a review from brainexe September 22, 2026 15:42
@kofrezo kofrezo self-assigned this Sep 22, 2026
@kofrezo kofrezo added enhancement ai Code fully or partially AI generated. labels Sep 22, 2026
@kofrezo

kofrezo commented Sep 22, 2026

Copy link
Copy Markdown
Contributor Author

This code has been written with assistance of an LLM. I tested and verified and reviewed them myself. The improvements especially for bigger queries are quite impressive I saw queries dropping from 40 to 5 seconds runtime.

@brainexe brainexe left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

code looks valid + did some local tests and it still produced the expected results

@kofrezo
kofrezo merged commit 3c684f7 into main Sep 23, 2026
5 checks passed
@kofrezo
kofrezo deleted the dk_group_exists_for_related_attrs branch September 23, 2026 06:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ai Code fully or partially AI generated. enhancement

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants