[英]How to optimize sql query with subqueries, perhaps by lateral join?
I'm trying to optimize sophisticated sql query, it would be executed on each map bonding box change. 我正在尝试优化复杂的sql查询,它将在每次地图绑定框更改时执行。 I thought that
INNER LATERAL JOIN
would be fastest but it isn't. 我以为
INNER LATERAL JOIN
最快,但不是。 Does anybody know how to speed up this query and how to make better use of LATERAL JOIN
? 有人知道如何加快查询速度,以及如何更好地利用
LATERAL JOIN
吗?
The fastest query I've made: 我进行的最快查询:
SELECT r0."id", r0."name"
FROM "hiking"."routes" AS r0
INNER JOIN "hiking"."hierarchy" AS h1 ON r0."id" = h1."parent"
INNER JOIN (SELECT DISTINCT unnest(s0."rels") AS "rel"
FROM "hiking"."segments" AS s0
WHERE (ST_Intersects(s0."geom", ST_SetSrid(ST_MakeBox2D(ST_GeomFromText('POINT(1285982.015631 7217169.814674)', -1), ST_GeomFromText('POINT(2371999.313507 6454022.524275)', -1)), 3857)))) AS s2 ON TRUE
WHERE (s2."rel" = h1."child");
Planning time: ~0.605 ms Execution time: ~37.232 ms
计划时间:〜0.605毫秒执行时间:〜37.232毫秒
Actually the same as above but with LATERAL JOIN
, is it correct that it is slower? 实际上与上面相同,但使用
LATERAL JOIN
,速度较慢是否正确?
SELECT r0."id", r0."name"
FROM "hiking"."routes" AS r0
INNER JOIN "hiking"."hierarchy" AS h1 ON r0."id" = h1."parent"
INNER JOIN LATERAL (SELECT DISTINCT unnest(s0."rels") AS "rel"
FROM "hiking"."segments" AS s0
WHERE (ST_Intersects(s0."geom", ST_SetSrid(ST_MakeBox2D(ST_GeomFromText('POINT(1285982.015631 7217169.814674)', -1), ST_GeomFromText('POINT(2371999.313507 6454022.524275)', -1)), 3857)))) AS s2 ON TRUE
WHERE (s2."rel" = h1."child");
Planning time: ~1.353 ms Execution time: ~38.518 ms
计划时间:〜1.353毫秒执行时间:〜38.518毫秒
Slowest query with subquery in subquery (that was my first so I've improved it a bit): 子查询中子查询中最慢的查询(这是我的第一个查询,因此我对其进行了一些改进):
SELECT r0."id", r0."name"
FROM "hiking"."routes" AS r0
INNER JOIN (SELECT DISTINCT h0."parent" AS "parent"
FROM "hiking"."hierarchy" AS h0
INNER JOIN (SELECT DISTINCT unnest(s0."rels") AS "rel"
FROM "hiking"."segments" AS s0
WHERE (ST_Intersects(s0."geom", ST_SetSrid(ST_MakeBox2D(ST_GeomFromText('POINT(1285982.015631 7217169.814674)', -1), ST_GeomFromText('POINT(2371999.313507 6454022.524275)', -1)), 3857)))) AS s1 ON TRUE
WHERE (h0."child" = s1."rel")) AS s1 ON TRUE
WHERE (r0."top" AND (r0."id" = s1."parent"));
Planning time: ~1.017 ms Execution time: ~41.288 ms
计划时间:〜1.017毫秒执行时间:〜41.288毫秒
It is hard to reproduce the logic of your query without any knowledges about your DB but I will try, so be patient: 在没有任何有关数据库的知识的情况下,很难重现查询的逻辑,但是我会尽力的,所以请耐心等待:
SELECT r0."id", r0."name"
FROM "hiking"."routes" AS r0
INNER JOIN "hiking"."hierarchy" AS h1 ON r0."id" = h1."parent"
WHERE
EXISTS (
SELECT 1
FROM "hiking"."segments" AS s0
WHERE (
ST_Intersects(
s0."geom",
ST_SetSrid(ST_MakeBox2D(ST_GeomFromText('POINT(1285982.015631 7217169.814674)', -1), ST_GeomFromText('POINT(2371999.313507 6454022.524275)', -1)),
3857)))
AND array[h1."child"] <@ s0."rels");
There are two points: 有两点:
EXISTS
or NOT EXISTS
sometimes faster then by joining EXISTS
或NOT EXISTS
筛选数据有时会比通过加入来更快 Here is simple example how to use indexes on arrays and how its faster: 这是一个简单的示例,说明如何在数组上使用索引及其速度如何:
create table foo(bar int[]);
insert into foo(bar) select array[1,2,3,x] from generate_series(1,1000000) as x;
create index idx on foo using gin (bar); // Note this
select * from foo where 666 in (select unnest(bar)); // 6936,345 ms on my HW
select * from foo where array[666] <@ bar; // 45,524 ms
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.