mirror of
https://github.com/hasura/graphql-engine.git
synced 2024-12-16 01:44:03 +03:00
fa152d842d
> ### Description > This PR supersedes https://github.com/hasura/graphql-engine-mono/pull/1484. Apply `limit` to the table selection before joining relationship rows to improve query performance. ### Changelog - [x] `CHANGELOG.md` is updated with user-facing content relevant to this PR. If no changelog is required, then add the `no-changelog-required` label. ### Affected components - [x] Server ### Related Issues -> Fix https://github.com/hasura/graphql-engine/issues/5745 ### Solution and Design > Prior to this change, we apply `LIMIT` and `OFFSET` to the outer selection from sub-query which includes joins for relationships. Now, we move `LIMIT` and `OFFSET` (if present) to inner selection of base table. But, this isn't done always! If there are order by relationships' columns we apply at the outer selection. To know more, please refer to [source code note](https://github.com/hasura/graphql-engine-mono/pull/2078/files#diff-46d868ee45d3eaac667cebb34731f573c77d5c9c8097bb9ccf1115fc07f65bfdR652). ```graphql query { article(limit: 2){ id title content author{ name } } } ``` Before: ```sql SELECT coalesce(json_agg("root"), '[]') AS "root" FROM ( SELECT row_to_json( ( SELECT "_4_e" FROM ( SELECT "_0_root.base"."id" AS "id", "_0_root.base"."title" AS "title", "_0_root.base"."content" AS "content", "_3_root.or.author"."author" AS "author" ) AS "_4_e" ) ) AS "root" FROM ( SELECT * FROM "public"."article" WHERE ('true') ) AS "_0_root.base" LEFT OUTER JOIN LATERAL ( SELECT row_to_json( ( SELECT "_2_e" FROM ( SELECT "_1_root.or.author.base"."name" AS "name" ) AS "_2_e" ) ) AS "author" FROM ( SELECT * FROM "public"."author" WHERE (("_0_root.base"."author_id") = ("id")) ) AS "_1_root.or.author.base" ) AS "_3_root.or.author" ON ('true') LIMIT 2 ) AS "_5_root" ``` cost ``` Aggregate (cost=0.73..0.74 rows=1 width=32) -> Limit (cost=0.15..0.71 rows=2 width=32) -> Nested Loop Left Join (cost=0.15..223.96 rows=810 width=32) -> Seq Scan on article (cost=0.00..18.10 rows=810 width=72) -> Index Scan using author_pkey on author (cost=0.15..0.24 rows=1 width=36) Index Cond: (article.author_id = id) SubPlan 1 -> Result (cost=0.00..0.01 rows=1 width=32) SubPlan 2 -> Result (cost=0.00..0.01 rows=1 width=32) ``` After: ```sql SELECT coalesce(json_agg("root"), '[]') AS "root" FROM ( SELECT row_to_json( ( SELECT "_4_e" FROM ( SELECT "_0_root.base"."id" AS "id", "_0_root.base"."title" AS "title", "_0_root.base"."content" AS "content", "_3_root.or.author"."author" AS "author" ) AS "_4_e" ) ) AS "root" FROM ( SELECT * FROM "public"."article" WHERE ('true') LIMIT 2 ) AS "_0_root.base" LEFT OUTER JOIN LATERAL ( SELECT row_to_json( ( SELECT "_2_e" FROM ( SELECT "_1_root.or.author.base"."name" AS "name" ) AS "_2_e" ) ) AS "author" FROM ( SELECT * FROM "public"."author" WHERE (("_0_root.base"."author_id") = ("id")) ) AS "_1_root.or.author.base" ) AS "_3_root.or.author" ON ('true') ) AS "_5_root" ``` cost: ``` Aggregate (cost=16.47..16.48 rows=1 width=32) -> Nested Loop Left Join (cost=0.15..16.44 rows=2 width=100) -> Limit (cost=0.00..0.04 rows=2 width=72) -> Seq Scan on article (cost=0.00..18.10 rows=810 width=72) -> Index Scan using author_pkey on author (cost=0.15..8.18 rows=1 width=36) Index Cond: (article.author_id = id) SubPlan 1 -> Result (cost=0.00..0.01 rows=1 width=32) SubPlan 2 -> Result (cost=0.00..0.01 rows=1 width=32) ``` https://github.com/hasura/graphql-engine-mono/pull/2078 Co-authored-by: Evie Ciobanu <1017953+eviefp@users.noreply.github.com> GitOrigin-RevId: 47eaccdbfb3499efd2c9f733f3312ad31c77916f |
||
---|---|---|
.. | ||
Control | ||
Data | ||
GHC/Stats | ||
Hasura | ||
Network |