直接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时会反转。

相关推荐
2501_9142459320 小时前
SQL如何统计分组内满足条件的唯一项_COUNT与DISTINCT
jvm·数据库·python
chen_ever20 小时前
Redis详解|从基础到面试高频题
数据库·redis·后端·缓存
弱水三千 只取一瓢饮20 小时前
sqlserver 从数据库A的备份文件,还原到数据库B中
数据库·sqlserver
池佳齐20 小时前
软考高级系统架构设计师备考(十八):数据库系统—事务管理与并发控制
数据库·oracle·系统架构
数智化精益手记局20 小时前
8d报告案例分析:拆解8d报告案例分析的8个步骤,解决生产现场重复发生的质量难题
大数据·数据结构·数据库·人工智能·精益工程
qq_1898070320 小时前
C#怎么操作数据库存储过程 C#如何调用SQL Server存储过程传参并获取返回结果【数据库】
jvm·数据库·python
m0_7467523020 小时前
HTML5视频标签针对不同设备DPR的资源选择逻辑
jvm·数据库·python
2301_7735536220 小时前
c++怎么在Linux下获取文件被最后一次访问的精确纳秒时间【进阶】
jvm·数据库·python
是宇写的啊20 小时前
MyBatis-3
数据库
gmaajt20 小时前
CSS如何给按钮添加按下缩小的动画_利用-active配合transform
jvm·数据库·python