直接case when 聚合和先聚合后case when在duckdb150和sqlite3.52的性能比较

同样对10000000行的内存表执行2个值分别和7个值和11个值的复合分组聚合。

sql 复制代码
C:\d>duckdb150
DuckDB v1.5.0 (Variegata)
Enter ".help" for usage hints.
memory D .timer on
memory D create table t as select i%2 a, i%7 b,i%11 c from range(1,10000000)t(i);
Run Time (s): real 0.288 user 0.234375 sys 0.046875
memory D select a,
         count(case b when 0 then 1 end)b0 ,
         count(case b when 1 then 1 end)b1 ,
         count(case b when 2 then 1 end)b2 ,
         count(case b when 3 then 1 end)b3 ,
         count(case b when 4 then 1 end)b4 ,
         count(case b when 5 then 1 end)b5 ,
         count(case b when 6 then 1 end)b5
         from t group by a;
┌───────┬────────┬────────┬────────┬────────┬────────┬────────┬────────┐
│   a   │   b0   │   b1   │   b2   │   b3   │   b4   │   b5   │   b5   │
│ int64 │ int64  │ int64  │ int64  │ int64  │ int64  │ int64  │ int64  │
├───────┼────────┼────────┼────────┼────────┼────────┼────────┼────────┤
│     0 │ 714285 │ 714286 │ 714286 │ 714285 │ 714286 │ 714285 │ 714286 │
│     1 │ 714286 │ 714286 │ 714286 │ 714286 │ 714285 │ 714286 │ 714285 │
└───────┴────────┴────────┴────────┴────────┴────────┴────────┴────────┘
Run Time (s): real 0.051 user 0.171875 sys 0.203125
memory D with t1 as(select count(*)cnt ,a,b from t group by a,b)
         select a,
         sum(case b when 0 then cnt end)b0 ,
         sum(case b when 1 then cnt end)b1 ,
         sum(case b when 2 then cnt end)b2 ,
         sum(case b when 3 then cnt end)b3 ,
         sum(case b when 4 then cnt end)b4 ,
         sum(case b when 5 then cnt end)b5 ,
         sum(case b when 6 then cnt end)b5
         from t1 group by a;
┌───────┬────────┬────────┬────────┬────────┬────────┬────────┬────────┐
│   a   │   b0   │   b1   │   b2   │   b3   │   b4   │   b5   │   b5   │
│ int64 │ int128 │ int128 │ int128 │ int128 │ int128 │ int128 │ int128 │
├───────┼────────┼────────┼────────┼────────┼────────┼────────┼────────┤
│     0 │ 714285 │ 714286 │ 714286 │ 714285 │ 714286 │ 714285 │ 714286 │
│     1 │ 714286 │ 714286 │ 714286 │ 714286 │ 714285 │ 714286 │ 714285 │
└───────┴────────┴────────┴────────┴────────┴────────┴────────┴────────┘
Run Time (s): real 0.021 user 0.156250 sys 0.031250
memory D select a,
         count(case c when 0 then 1 end)c0 ,
         count(case c when 1 then 1 end)c1 ,
         count(case c when 2 then 1 end)c2 ,
         count(case c when 3 then 1 end)c3 ,
         count(case c when 4 then 1 end)c4 ,
         count(case c when 5 then 1 end)c5 ,
         count(case c when 6 then 1 end)c6 ,
         count(case c when 7 then 1 end)c7 ,
         count(case c when 8 then 1 end)c8 ,
         count(case c when 9 then 1 end)c9 ,
         count(case c when 10 then 1 end)c10
         from t group by a;
┌───────┬────────┬────────┬────────┬────────┬────────┬────────┬────────┬────────┬────────┬────────┬────────┐
│   a   │   c0   │   c1   │   c2   │   c3   │   c4   │   c5   │   c6   │   c7   │   c8   │   c9   │  c10   │
│ int64 │ int64  │ int64  │ int64  │ int64  │ int64  │ int64  │ int64  │ int64  │ int64  │ int64  │ int64  │
├───────┼────────┼────────┼────────┼────────┼────────┼────────┼────────┼────────┼────────┼────────┼────────┤
│     0 │ 454545 │ 454545 │ 454546 │ 454545 │ 454546 │ 454545 │ 454546 │ 454545 │ 454546 │ 454545 │ 454545 │
│     1 │ 454545 │ 454546 │ 454545 │ 454546 │ 454545 │ 454546 │ 454545 │ 454546 │ 454545 │ 454546 │ 454545 │
└───────┴────────┴────────┴────────┴────────┴────────┴────────┴────────┴────────┴────────┴────────┴────────┘
Run Time (s): real 0.061 user 0.406250 sys 0.093750
memory D with t1 as(select count(*)cnt ,a,c from t group by a,c)
         select a,
         sum(case c when 0 then cnt end)c0 ,
         sum(case c when 1 then cnt end)c1 ,
         sum(case c when 2 then cnt end)c2 ,
         sum(case c when 3 then cnt end)c3 ,
         sum(case c when 4 then cnt end)c4 ,
         sum(case c when 5 then cnt end)c5 ,
         sum(case c when 6 then cnt end)c6 ,
         sum(case c when 7 then cnt end)c7 ,
         sum(case c when 8 then cnt end)c8 ,
         sum(case c when 9 then cnt end)c9 ,
         sum(case c when 10 then cnt end)c10
         from t1 group by a;
┌───────┬────────┬────────┬────────┬────────┬────────┬────────┬────────┬────────┬────────┬────────┬────────┐
│   a   │   c0   │   c1   │   c2   │   c3   │   c4   │   c5   │   c6   │   c7   │   c8   │   c9   │  c10   │
│ int64 │ int128 │ int128 │ int128 │ int128 │ int128 │ int128 │ int128 │ int128 │ int128 │ int128 │ int128 │
├───────┼────────┼────────┼────────┼────────┼────────┼────────┼────────┼────────┼────────┼────────┼────────┤
│     0 │ 454545 │ 454545 │ 454546 │ 454545 │ 454546 │ 454545 │ 454546 │ 454545 │ 454546 │ 454545 │ 454545 │
│     1 │ 454545 │ 454546 │ 454545 │ 454546 │ 454545 │ 454546 │ 454545 │ 454546 │ 454545 │ 454546 │ 454545 │
└───────┴────────┴────────┴────────┴────────┴────────┴────────┴────────┴────────┴────────┴────────┴────────┘
Run Time (s): real 0.024 user 0.015625 sys 0.000000
memory D pivot(select count(*)cnt ,a,b from t group by a,b) on b using sum(cnt) ;
┌───────┬────────┬────────┬────────┬────────┬────────┬────────┬────────┐
│   a   │   0    │   1    │   2    │   3    │   4    │   5    │   6    │
│ int64 │ int128 │ int128 │ int128 │ int128 │ int128 │ int128 │ int128 │
├───────┼────────┼────────┼────────┼────────┼────────┼────────┼────────┤
│     0 │ 714285 │ 714286 │ 714286 │ 714285 │ 714286 │ 714285 │ 714286 │
│     1 │ 714286 │ 714286 │ 714286 │ 714286 │ 714285 │ 714286 │ 714285 │
└───────┴────────┴────────┴────────┴────────┴────────┴────────┴────────┘
Run Time (s): real 0.037 user 0.000000 sys 0.000000
memory D pivot(select count(*)cnt ,a,c from t group by a,c) on c using sum(cnt) ;
┌───────┬────────┬────────┬────────┬────────┬────────┬────────┬────────┬────────┬────────┬────────┬────────┐
│   a   │   0    │   1    │   10   │   2    │   3    │   4    │   5    │   6    │   7    │   8    │   9    │
│ int64 │ int128 │ int128 │ int128 │ int128 │ int128 │ int128 │ int128 │ int128 │ int128 │ int128 │ int128 │
├───────┼────────┼────────┼────────┼────────┼────────┼────────┼────────┼────────┼────────┼────────┼────────┤
│     0 │ 454545 │ 454545 │ 454545 │ 454546 │ 454545 │ 454546 │ 454545 │ 454546 │ 454545 │ 454546 │ 454545 │
│     1 │ 454545 │ 454546 │ 454545 │ 454545 │ 454546 │ 454545 │ 454546 │ 454545 │ 454546 │ 454545 │ 454546 │
└───────┴────────┴────────┴────────┴────────┴────────┴────────┴────────┴────────┴────────┴────────┴────────┘
Run Time (s): real 0.031 user 0.171875 sys 0.015625
memory D pivot t on b using count(*) group by a;
┌───────┬────────┬────────┬────────┬────────┬────────┬────────┬────────┐
│   a   │   0    │   1    │   2    │   3    │   4    │   5    │   6    │
│ int64 │ int64  │ int64  │ int64  │ int64  │ int64  │ int64  │ int64  │
├───────┼────────┼────────┼────────┼────────┼────────┼────────┼────────┤
│     0 │ 714285 │ 714286 │ 714286 │ 714285 │ 714286 │ 714285 │ 714286 │
│     1 │ 714286 │ 714286 │ 714286 │ 714286 │ 714285 │ 714286 │ 714285 │
└───────┴────────┴────────┴────────┴────────┴────────┴────────┴────────┘
Run Time (s): real 0.109 user 1.015625 sys 0.125000
memory D pivot t on c using count(*) group by a;
┌───────┬────────┬────────┬────────┬────────┬────────┬────────┬────────┬────────┬────────┬────────┬────────┐
│   a   │   0    │   1    │   10   │   2    │   3    │   4    │   5    │   6    │   7    │   8    │   9    │
│ int64 │ int64  │ int64  │ int64  │ int64  │ int64  │ int64  │ int64  │ int64  │ int64  │ int64  │ int64  │
├───────┼────────┼────────┼────────┼────────┼────────┼────────┼────────┼────────┼────────┼────────┼────────┤
│     0 │ 454545 │ 454545 │ 454545 │ 454546 │ 454545 │ 454546 │ 454545 │ 454546 │ 454545 │ 454546 │ 454545 │
│     1 │ 454545 │ 454546 │ 454545 │ 454545 │ 454546 │ 454545 │ 454546 │ 454545 │ 454546 │ 454545 │ 454546 │
└───────┴────────┴────────┴────────┴────────┴────────┴────────┴────────┴────────┴────────┴────────┴────────┘
Run Time (s): real 0.115 user 1.421875 sys 0.015625

DuckDB无论case when 7次和11次,都是先聚合更快。pivot比等价的手工case when慢一些。

sql 复制代码
SQLite version 3.52.0 2026-03-06 16:01:44
Enter ".help" for usage hints.
Connected to a transient in-memory database.
Use ".open FILENAME" to reopen on a persistent database.
sqlite> .timer on
sqlite> create table t as select i%2 a, i%7 b,i%11 c from (select value i from generate_series(1,10000000));
Run Time: real 0.803898 user 0.781250 sys 0.015625
sqlite> select a,
   ...> count(case b when 0 then 1 end)b0 ,
   ...> count(case b when 1 then 1 end)b1 ,
   ...> count(case b when 2 then 1 end)b2 ,
   ...> count(case b when 3 then 1 end)b3 ,
   ...> count(case b when 4 then 1 end)b4 ,
   ...> count(case b when 5 then 1 end)b5 ,
   ...> count(case b when 6 then 1 end)b5
   ...> from t group by a;
╭───┬────────┬────────┬────────┬────────┬────────┬────────┬────────╮
│ a │   b0   │   b1   │   b2   │   b3   │   b4   │   b5   │   b5   │
╞═══╪════════╪════════╪════════╪════════╪════════╪════════╪════════╡
│ 0 │ 714285 │ 714286 │ 714286 │ 714286 │ 714286 │ 714285 │ 714286 │
│ 1 │ 714286 │ 714286 │ 714286 │ 714286 │ 714285 │ 714286 │ 714285 │
╰───┴────────┴────────┴────────┴────────┴────────┴────────┴────────╯
Run Time: real 2.634213 user 2.515625 sys 0.109375
sqlite> with t1 as(select count(*)cnt ,a,b from t group by a,b)
   ...> select a,
   ...> sum(case b when 0 then cnt end)b0 ,
   ...> sum(case b when 1 then cnt end)b1 ,
   ...> sum(case b when 2 then cnt end)b2 ,
   ...> sum(case b when 3 then cnt end)b3 ,
   ...> sum(case b when 4 then cnt end)b4 ,
   ...> sum(case b when 5 then cnt end)b5 ,
   ...> sum(case b when 6 then cnt end)b5
   ...> from t1 group by a;
╭───┬────────┬────────┬────────┬────────┬────────┬────────┬────────╮
│ a │   b0   │   b1   │   b2   │   b3   │   b4   │   b5   │   b5   │
╞═══╪════════╪════════╪════════╪════════╪════════╪════════╪════════╡
│ 0 │ 714285 │ 714286 │ 714286 │ 714286 │ 714286 │ 714285 │ 714286 │
│ 1 │ 714286 │ 714286 │ 714286 │ 714286 │ 714285 │ 714286 │ 714285 │
╰───┴────────┴────────┴────────┴────────┴────────┴────────┴────────╯
Run Time: real 3.167292 user 3.031250 sys 0.125000
sqlite> select a,
   ...> count(case c when 0 then 1 end)c0 ,
   ...> count(case c when 1 then 1 end)c1 ,
   ...> count(case c when 2 then 1 end)c2 ,
   ...> count(case c when 3 then 1 end)c3 ,
   ...> count(case c when 4 then 1 end)c4 ,
   ...> count(case c when 5 then 1 end)c5 ,
   ...> count(case c when 6 then 1 end)c6 ,
   ...> count(case c when 7 then 1 end)c7 ,
   ...> count(case c when 8 then 1 end)c8 ,
   ...> count(case c when 9 then 1 end)c9 ,
   ...> count(case c when 10 then 1 end)c10
   ...> from t group by a;
╭───┬────────┬────────┬────────┬────────┬────────┬────────┬────────┬────────┬────────┬────────┬────────╮
│ a │   c0   │   c1   │   c2   │   c3   │   c4   │   c5   │   c6   │   c7   │   c8   │   c9   │  c10   │
╞═══╪════════╪════════╪════════╪════════╪════════╪════════╪════════╪════════╪════════╪════════╪════════╡
│ 0 │ 454545 │ 454545 │ 454546 │ 454545 │ 454546 │ 454545 │ 454546 │ 454545 │ 454546 │ 454545 │ 454546 │
│ 1 │ 454545 │ 454546 │ 454545 │ 454546 │ 454545 │ 454546 │ 454545 │ 454546 │ 454545 │ 454546 │ 454545 │
╰───┴────────┴────────┴────────┴────────┴────────┴────────┴────────┴────────┴────────┴────────┴────────╯
Run Time: real 3.113160 user 2.890625 sys 0.218750
sqlite> with t1 as(select count(*)cnt ,a,c from t group by a,c)
   ...> select a,
   ...> sum(case c when 0 then cnt end)c0 ,
   ...> sum(case c when 1 then cnt end)c1 ,
   ...> sum(case c when 2 then cnt end)c2 ,
   ...> sum(case c when 3 then cnt end)c3 ,
   ...> sum(case c when 4 then cnt end)c4 ,
   ...> sum(case c when 5 then cnt end)c5 ,
   ...> sum(case c when 6 then cnt end)c6 ,
   ...> sum(case c when 7 then cnt end)c7 ,
   ...> sum(case c when 8 then cnt end)c8 ,
   ...> sum(case c when 9 then cnt end)c9 ,
   ...> sum(case c when 10 then cnt end)c10
   ...> from t1 group by a;
╭───┬────────┬────────┬────────┬────────┬────────┬────────┬────────┬────────┬────────┬────────┬────────╮
│ a │   c0   │   c1   │   c2   │   c3   │   c4   │   c5   │   c6   │   c7   │   c8   │   c9   │  c10   │
╞═══╪════════╪════════╪════════╪════════╪════════╪════════╪════════╪════════╪════════╪════════╪════════╡
│ 0 │ 454545 │ 454545 │ 454546 │ 454545 │ 454546 │ 454545 │ 454546 │ 454545 │ 454546 │ 454545 │ 454546 │
│ 1 │ 454545 │ 454546 │ 454545 │ 454546 │ 454545 │ 454546 │ 454545 │ 454546 │ 454545 │ 454546 │ 454545 │
╰───┴────────┴────────┴────────┴────────┴────────┴────────┴────────┴────────┴────────┴────────┴────────╯
Run Time: real 3.251369 user 3.046875 sys 0.171875
sqlite>

SQLite无论case when 7次和11次,都是后聚合更快。11次的两种方法差距更小,预计更多项需要case when时会反转。

相关推荐
爆炒西瓜@2 小时前
springboot内存定位,提取数据库账号密码
数据库·spring boot·后端
数据知道2 小时前
MongoDB分片集群部署:详细生产环境完整搭建
数据库·mongodb
bropro2 小时前
MySQL不使用子查询的原因
android·数据库·mysql
野生技术架构师2 小时前
Java面试精选:数据库 + 数据结构 +JVM+ 网络 +JAVA+ 分布式
java·数据库·面试
枫叶丹2 小时前
复杂SQL性能突围:代价驱动的连接条件下推策略与工程实践
数据库
fengye2071612 小时前
MongoDB 安装与配置
数据库·mongodb
银河麒麟操作系统2 小时前
银河麒麟服务器操作系统IO机制详解
数据库·redis·缓存
OxyTheCrack3 小时前
【C++】一篇文章悲观锁与乐观锁与其思想在C++语言中的应用
linux·开发语言·数据库·c++·笔记
执笔论英雄3 小时前
【cuda】 pinpaged
android·java·数据库