分类: Mysql/postgreSQL
2019-01-23 16:15:08
-- 建立表 postgres=# create table t(i int); CREATE TABLE -- 插入数据 postgres=# insert into t(i) select i from generate_series(1, 10000) t(i); INSERT 0 10000 -- 创建索引,为了后面的演示 postgres=# create index on t(i); CREATE INDEX -- 使用where 进行统计 postgres=# select count(*) from t where i > 10 and i < 100; count ------- 89 -- 在where的情况下再做filter postgres=# select count(*) cnt, count(*) filter(where i > 20 and i < 60) cnt2 from t where i > 10 and i < 100; cnt | cnt2 -----+------ 89 | 39
-- where中使用了索引 postgres=# explain select count(*) from t where i > 10 and i < 100; QUERY PLAN ------------------------------------------------------------------------------ Aggregate (cost=10.29..10.30 rows=1 width=8) -> Index Only Scan using t_i_idx on t (cost=0.29..10.07 rows=89 width=0) Index Cond: ((i > 10) AND (i < 100)) -- 同样是这个条件,filter不走索引 postgres=# explain select count(*) filter(where i > 10 and i < 100) from t; QUERY PLAN ------------------------------------------------------------- Aggregate (cost=220.00..220.01 rows=1 width=8) -> Seq Scan on t (cost=0.00..145.00 rows=10000 width=4)
-- cnt1, cnt2 等价 postgres=# select count(*) cnt, count(*) filter(where i > 10 and i < 100) cnt1, count(case when i > 10 and i < 100 then 1 else null end) cnt2 from t; --- cnt | cnt1 | cnt2 -------+------+------ 10000 | 89 | 89
结论:filter 比原来的case when实现更加优雅简单