Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: use exists for relational filters #5104

Open
wants to merge 10 commits into
base: main
Choose a base branch
from

Conversation

jacek-prisma
Copy link
Contributor

@jacek-prisma jacek-prisma commented Jan 6, 2025

ORM-395
Closes prisma/prisma#25731

This PR changes all the relational filters to use correlated queries with a WHERE clause referring to a table from the outer query instead of IN, e.g:

SELECT COUNT(*)
FROM (
  SELECT "public"."Issue"."id"
  FROM "public"."Issue"
  WHERE ("public"."Issue"."id") NOT IN (
    SELECT "t1"."A"
	FROM "public"."_IssueToUser" AS "t1"
	INNER JOIN "public"."User" AS "j1"
	ON ("j1"."id") = ("t1"."B")
	WHERE (1=1 AND "t1"."A" IS NOT NULL)
  )
) AS "sub"

becomes

SELECT COUNT(*)
FROM (
  SELECT "public"."Issue"."id"
  FROM "public"."Issue"
  WHERE NOT EXISTS (
    SELECT "t1"."A"
	FROM "public"."_IssueToUser" AS "t1"
	INNER JOIN "public"."User" AS "j1"
	ON ("j1"."id") = ("t1"."B")
	WHERE (1=1 AND "t1"."A" IS NOT NULL) AND ("public"."Issue"."id" = "t1"."A")
  )
) AS "sub"

Notes:

  • I've had to change the alias generation code a little bit because the counters weren't being reused properly which led to name clashes with the correlated query. I've moved the counter into Context to make sure we always use the same counter.
  • In postgres16 specifically the results seem to be ordered inconsistently for some of the EXISTS filters, I don't think that's a problem, but it did break some tests. I updated these tests with orderBy.
  • The code now outputs correlated queries for relational filters, which should generally be very efficient because relational filters always query for identifier columns, but there's no guarantee that this is always going to be faster. It might be worth investigating the performance impact in different queries and databases.

Copy link

codspeed-hq bot commented Jan 6, 2025

CodSpeed Performance Report

Merging #5104 will not alter performance

Comparing feat/relation-exists (3d318b6) with main (4123509)

Summary

✅ 11 untouched benchmarks

Copy link
Contributor

github-actions bot commented Jan 6, 2025

WASM Query Engine file Size

Engine This PR Base branch Diff
Postgres 2.097MiB 2.096MiB 885.000B
Postgres (gzip) 841.250KiB 841.363KiB -116.000B
Mysql 2.058MiB 2.057MiB 1010.000B
Mysql (gzip) 827.479KiB 827.871KiB -401.000B
Sqlite 1.972MiB 1.972MiB -240.000B
Sqlite (gzip) 791.929KiB 792.450KiB -533.000B

@jacek-prisma jacek-prisma marked this pull request as ready for review January 7, 2025 14:57
@jacek-prisma jacek-prisma requested a review from a team as a code owner January 7, 2025 14:57
@jacek-prisma jacek-prisma requested review from wmadden and removed request for a team January 7, 2025 14:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Query for empty relations is very slow for many-to-many relation
1 participant