我有这样的查询:
SELECT x.id
FROM x
LEFT JOIN (
SELECT a.id FROM a
WHERE [condition1] [condition2]
) AS A USING (id)
LEFT JOIN (
SELECT b.id FROM b
WHERE [condition1] [condition3]
) AS B USING (id)
LEFT JOIN (
SELECT c.id FROM c
WHERE [condition1] [condition4]
) AS C USING (id)
WHERE [condition1]
正如您所看到的,[condition1]
对于子查询和外部查询是常见的。
出于性能原因,[一般]是否值得从子查询中删除[condition1]
(因为结果相同)?请不要给出“跑它看”这样的答案。有很多数据及其变化,因此我们需要良好的最坏情况行为。
我曾试图做一些测试,但他们远未定论。 Postgres是否会发现条件也适用于子查询并传播它?
condition1
的示例:
WHERE a.id NOT IN (SELECT id FROM {ft_geom_in})
(这很慢,我知道,这只是举例)WHERE a.id > x
答案 0 :(得分:0)
很难给出明确的一般答案,因为很大程度上取决于实际的数据模型(尤其是索引)和查询(条件)。
但是,在许多情况下,将condition1
放在已连接的子查询中是有意义的。
这尤其适用于condition2
排除的行数少于condition1
的情况。
在这种情况下,condition1
上的过滤器可能会显着减少condition2
的检查次数。
另一方面,子查询中condition1
的存在似乎不太可能大大减慢查询速度。
简单测试不提供一般答案,但可以作为说明。
create table x (id integer, something text);
create table a (id integer, something text);
insert into x select i, i::text from generate_series (1, 1000000) i;
insert into a select i, i::text from generate_series (1, 1000000) i;
查询A:condition2
排除了几行。
A1:condition1
explain analyse
select x.id
from x
left join (
select id from a
where id < 500000 and length(something) > 1
) as a using (id)
where id < 500000;
Average execution time: ~620.000 ms
A2:没有condition1
explain analyse
select x.id
from x
left join (
select id from a
where length(something) > 1
) as a using (id)
where id < 500000;
Average execution time: ~810.000 ms
查询B:condition2
排除了很多行。
B1:condition1
explain analyse
select x.id
from x
left join (
select id from a
where id < 500000 and length(something) = 1
) as a using (id)
where id < 500000;
Average execution time: ~220.000 ms
B2:没有condition1
explain analyse
select x.id
from x
left join (
select id from a
where length(something) = 1
) as a using (id)
where id < 500000;
Average execution time: ~230.000 ms
请注意,查询不需要包含子查询。具有简单左连接和公共where clause
条件的查询应该更快一些。例如,这相当于查询B1:
explain analyse
select x.id
from x
left join a using(id)
where x.id < 500000
and a.id < 500000
and length(a.something) = 1
Average execution time: ~210.000 ms