同样对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时会反转。