为什么 PostgreSQL 按布尔 WHERE 条件排序?
Why does PostgreSQL sorts on a boolean WHERE condition?
我正在对一堆物化视图测试一些查询。它们都具有相同的结构,例如:
EXPLAIN ANALYZE SELECT mr.foo, ..., CAST(SUM(mr.bar) AS INTEGER) AS stuff
FROM foo.bar mr
WHERE
mr.a = 'TRUE' AND
mr.b = 'something' AND
mr.c = '12'
GROUP BY
mr.a,
mr.b,
mr.c;
很明显,系统为它们中的每一个都提供了不同的查询计划,但是如果(且仅当)WHERE 子句涉及布尔列(如示例中所示),计划程序 always 在完成之前对结果集进行排序。示例:
Finalize GroupAggregate (cost=16305.92..16317.98 rows=85 width=21) (actual time=108.301..108.301 rows=1 loops=1)
Group Key: festivo, nome_strada, ora
-> Gather Merge (cost=16305.92..16315.05 rows=70 width=77) (actual time=108.279..109.015 rows=2 loops=1)
Workers Planned: 2
Workers Launched: 2
-> Partial GroupAggregate (cost=15305.90..15306.95 rows=35 width=77) (actual time=101.422..101.422 rows=1 loops=3)
Group Key: festivo, nome_strada, ora
-> Sort (cost=15305.90..15305.99 rows=35 width=21) (actual time=101.390..101.395 rows=28 loops=3)
Sort Key: festivo
Sort Method: quicksort Memory: 25kB
-> Parallel Seq Scan on sft_vmv3_g3 mr (cost=0.00..15305.00 rows=35 width=21) (actual time=75.307..101.329 rows=28 loops=3)
Filter: (festivo AND ((nome_strada)::text = '16th St'::text) AND (ora = '12'::smallint))
Rows Removed by Filter: 277892
我对这种方法很好奇,但我仍然没有找到关于这个的解释。
我很好奇你为什么不将逻辑表述为:
SELECT true as a, 'something' as b, '12' as c, CAST(SUM(mr.bar) as INTEGER)
FROM foo.bar as mr
WHERE mr.a AND
mr.b = 'something' AND
mr.c = '12';
这是一个聚合查询(因为 SELECT
中的 SUM()
)并且没有明确的 GROUP BY
。我认为它应该产生一个更优化的执行计划。此外,它总是 return 一行,即使没有行符合条件。
我正在对一堆物化视图测试一些查询。它们都具有相同的结构,例如:
EXPLAIN ANALYZE SELECT mr.foo, ..., CAST(SUM(mr.bar) AS INTEGER) AS stuff
FROM foo.bar mr
WHERE
mr.a = 'TRUE' AND
mr.b = 'something' AND
mr.c = '12'
GROUP BY
mr.a,
mr.b,
mr.c;
很明显,系统为它们中的每一个都提供了不同的查询计划,但是如果(且仅当)WHERE 子句涉及布尔列(如示例中所示),计划程序 always 在完成之前对结果集进行排序。示例:
Finalize GroupAggregate (cost=16305.92..16317.98 rows=85 width=21) (actual time=108.301..108.301 rows=1 loops=1)
Group Key: festivo, nome_strada, ora
-> Gather Merge (cost=16305.92..16315.05 rows=70 width=77) (actual time=108.279..109.015 rows=2 loops=1)
Workers Planned: 2
Workers Launched: 2
-> Partial GroupAggregate (cost=15305.90..15306.95 rows=35 width=77) (actual time=101.422..101.422 rows=1 loops=3)
Group Key: festivo, nome_strada, ora
-> Sort (cost=15305.90..15305.99 rows=35 width=21) (actual time=101.390..101.395 rows=28 loops=3)
Sort Key: festivo
Sort Method: quicksort Memory: 25kB
-> Parallel Seq Scan on sft_vmv3_g3 mr (cost=0.00..15305.00 rows=35 width=21) (actual time=75.307..101.329 rows=28 loops=3)
Filter: (festivo AND ((nome_strada)::text = '16th St'::text) AND (ora = '12'::smallint))
Rows Removed by Filter: 277892
我对这种方法很好奇,但我仍然没有找到关于这个的解释。
我很好奇你为什么不将逻辑表述为:
SELECT true as a, 'something' as b, '12' as c, CAST(SUM(mr.bar) as INTEGER)
FROM foo.bar as mr
WHERE mr.a AND
mr.b = 'something' AND
mr.c = '12';
这是一个聚合查询(因为 SELECT
中的 SUM()
)并且没有明确的 GROUP BY
。我认为它应该产生一个更优化的执行计划。此外,它总是 return 一行,即使没有行符合条件。