Postgresql postgres CASE和where子句
假设我有一张像这样的桌子:Postgresql postgres CASE和where子句,postgresql,Postgresql,假设我有一张像这样的桌子: id item type status date 1 A 1 P 2018-04-01 2 B 2 A 2018-01-01 3 C 1 A 2018-01-02 4 D 2 A 2018-04-11 现在查询1: Select count(case when type=1 and status='A' and date<'
id item type status date
1 A 1 P 2018-04-01
2 B 2 A 2018-01-01
3 C 1 A 2018-01-02
4 D 2 A 2018-04-11
现在查询1:
Select count(case when type=1 and status='A' and date<'2018-04-01' then id) as type1,
count(case when type=2 and status='A' and date<'2018-04-01' then id)as type2
FROM table
和问题2:
Select count(case when type=1 then id) as type1,
count(case when type=2 then id)as type2
FROM table where status='A' and date < '2018-04-01'
这两个版本是否相同,如果是whcih更好如果日期列上有索引,那么第二个版本可能会比第一个版本更好。这样做的原因是,Postgres甚至可以在SELECT子句中进行条件聚合之前过滤掉WHERE中的许多记录
如果date没有索引,则无论哪种情况,Postgres都必须接触表中的每条记录。使用如下模式: 第二个查询执行得更好,原因是:
Rows Removed by Filter: 2
<>但它们都不使用任何索引,对于大量数据,您应该考虑添加新索引并再次检查性能。
dbfiddle请添加当前的表架构。
Rows Removed by Filter: 2
explain (analyze,buffers)
select count(case when type = 1 and status = 'A' and date < '2018-04-01' then id end) as type1,
count(case when type = 2 and status = 'A' and date < '2018-04-01' then id end) as type2
from tbl;
| QUERY PLAN |
| :---------------------------------------------------------------------------------------------------- |
| Aggregate (cost=33.40..33.41 rows=1 width=16) (actual time=0.022..0.022 rows=1 loops=1) |
| Buffers: shared hit=1 |
| -> Seq Scan on tbl (cost=0.00..17.80 rows=780 width=44) (actual time=0.006..0.007 rows=4 loops=1) |
| Buffers: shared hit=1 |
| Planning time: 0.171 ms |
| Execution time: 0.121 ms |
explain (analyze,buffers)
select count(case when type=1 then id end) as type1,
count(case when type=2 then id end)as type2
from tbl
where status = 'A'
and date < '2018-04-01';
| QUERY PLAN |
| :------------------------------------------------------------------------------------------------- |
| Aggregate (cost=21.71..21.72 rows=1 width=16) (actual time=0.007..0.008 rows=1 loops=1) |
| Buffers: shared hit=1 |
| -> Seq Scan on tbl (cost=0.00..21.70 rows=1 width=8) (actual time=0.004..0.005 rows=2 loops=1) |
| Filter: ((date < '2018-04-01'::date) AND (status = 'A'::text)) |
| Rows Removed by Filter: 2 |
| Buffers: shared hit=1 |
| Planning time: 0.084 ms |
| Execution time: 0.032 ms |