分析クエリは、探すクエリと読み方が違う
分析クエリとは、たくさんの行から合計や平均を求める問い合わせです。
行指向と列指向という保存のしかたの違いを知ると、分析用のデータベースがなぜ速いのかが分かります。
先に、売上表の合計を DuckDB で出してみましょう。
このレッスンのゴール
メモ
分析クエリは、探すクエリとは違う読み方で表を読むと説明できる。
重要な言葉
| ことば | いみ | れい |
|---|---|---|
| 分析クエリ | 多くの行をまとめて、合計や平均を求める問い合わせ | |
| 検索クエリ | 条件に合う数行を探し出す問い合わせ | 注文番号が 1024 の行 |
| 行指向 | 1行分の値をまとめて保存するしくみ | |
| 列指向 | 1列分の値をまとめて保存するしくみ | |
| 集計 | 複数の行を、合計や件数などの1つの値にまとめること | sum(qty) |
| DuckDB | 分析に向いた SQL データベース |
学生が入力するセルは、このプレビューでは空白です。
探すクエリは数行、分析クエリは何万行
検索クエリは、注文番号が 1024 の1行のように、少ない行を探します。その行の全部の列がほしいことが多いです。
分析クエリは、先月の売上の合計のように、何万行も読みます。ところが、使う列は2つか3つだけです。
例: 2つの問い合わせの違い
| 見ること | 検索クエリ | 分析クエリ |
|---|---|---|
| 問いの例 | 注文 1024 の中身は | 4月の売上の合計は |
| 読む行 | 1行から数行 | 何万行から何億行 |
| 使う列 | ほとんどの列 | 2つか3つの列 |
| 答え | 行そのもの | 合計や平均などの数字 |
学生が入力するセルは、このプレビューでは空白です。
試す: 弁当の数量の合計
-- 弁当の数量の合計を出します。読む列は category と qty だけです。
select sum(qty) as total_qty
from sales
where category = '弁当';
-- '弁当' を '飲み物' に変えて、もう一度実行しましょう。
列指向は、列ごとに値を並べて保存する
行指向のデータベースは、1行分の値を続けて保存します。1行をまるごと取り出すのが得意です。
列指向のデータベースは、同じ列の値を続けて保存します。DuckDB はこの形です。
合計に必要な列だけを読めば足りるので、読まない列には手を付けません。
例: 同じ3行の、2通りの保存
| 保存のしかた | 並び方 | 得意なこと |
|---|---|---|
| 行指向 | (1, 渋谷, 弁当, 3) (2, 渋谷, 飲み物, 5) (3, 新宿, 弁当, 2) | 1行をまるごと読む |
| 列指向 | id: 1, 2, 3 / store: 渋谷, 渋谷, 新宿 / category: 弁当, 飲み物, 弁当 / qty: 3, 5, 2 | 1列を端から端まで読む |
学生が入力するセルは、このプレビューでは空白です。
GROUP BY で、種類ごとに集計する
group by を付けると、種類ごとに行がまとまり、集計が種類ごとに出ます。
次の Run は category と qty と unit_price の3列だけを使います。表には store や sold_on もありますが、読まれません。
試す: 種類ごとの売上
-- 種類ごとに、件数と売上金額を出します。
select category, count(*) as n, sum(qty * unit_price) as yen
from sales
group by category
order by category;
-- 次は group by category を store に変えてみましょう。
-- select の category も store に変えます。
例: 種類ごとの売上の答え
| category | n | yen |
|---|---|---|
| 弁当 | 7 | 10700 |
| 飲み物 | 5 | 2860 |
学生が入力するセルは、このプレビューでは空白です。
よくある間違い
注意
分析クエリで select * と書くと、全部の列を読みます。列指向の良さが消えます。必要な列の名前だけを書きましょう。
さらに挑戦
注文表が1億行あり、列が20あるとします。合計に使う列は2つです。行指向と列指向で、読むデータの量がどれくらい違うか、自分の言葉で説明してください。
このページの表は12行しかないので、速さの差は見えません。差が出るのは、行も列も多い表です。