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

相关推荐
devilnumber1 小时前
Oracle 与 MySQL substr 函数差异总结
java·数据库·mysql·oracle
—Miss. Z—1 小时前
计算机等级考试三级数据库技术—选择题
数据库·mysql
www_aiyuanma_vip1 小时前
PC 手机电商(MySQL 版)
数据库·mysql·智能手机
Databend1 小时前
AI 时代的数据工程挑战:从复杂链路走向统一数据底座
大数据·数据库·云计算
treacle田2 小时前
达梦数据库-Linux DM数据守护主备集群缩改为单机-记录总结
linux·服务器·数据库·主备集群改单机
SelectDB技术团队2 小时前
Apache Doris 支持同步/异步物化视图与 ROLLUP,多表加速能力优于 StarRocks
大数据·数据库·doris·技术选型·物化视图·starrock·查询加速
super大力张2 小时前
MOE基于结构的药物设计(七):Ligand R-Vectors——如何判断配体可以从哪里继续生长?
数据库·算法·cadd·moe·svl·基于结构的药物设计
Databend2 小时前
Databend 增量物化视图:基于 Change Tracking 的增量刷新与一致性读取
大数据·数据库·sql
腾讯云开发者2 小时前
与数据库打了几十年交道,WorkBuddy让我有了「第二知识库」
数据库