カラムストアと整列
矢田 晋
@s5yata
有限会社未来検索ブラジル
自己紹介
• 所属
– 有限会社未来検索ブラジル

• 仕事内容
– カラムストア+全文検索(Grnxx)の開発

• 公開物
– トライのライブラリ(darts-clone, marisa-trie)
– 日本語 N-gram コーパス
20...
発表内容
カラムストアの

ORDER BY について
(独断と偏見により)
検討&実験してみた
2014年1月11日

カラムストアと整列

3
カラムストアって何?
• 縦に分割されているイメージ
ROWID
1

ColumnA
100

ColumnB
“Apple”

ColumnC
1.73

2
3
…
N–2
N–1
N

200
150
…
300
120
230

“B...
カラムストアの検索
• 条件に該当する行の一覧を作成する
– 例:ColumnA < 200 => { 1, 3, N – 1 }
ROWID

ColumnA

ColumnB

ColumnC

1

100

“Apple”

1.73
...
カラムストアの整列
• 行(ROWID)の一覧を整列する
– 例:ORDER BY ColumnC => { 3, N – 1, 1 }
ROWID

ColumnA

ColumnB

ColumnC

1

100

“Apple”

1....
問題を単純化しよう
• データ型

• 整列条件

– ROWID: UInt64
– Column: Int64

– 単一カラム
– 昇順固定

• データ

• 整列範囲

– 擬似乱数(mt19937)

– 上位 Limit 行

•...
サンプルコード
std::vector<Int64> column;
std::vector<RowID> rows;
generate_data(&column, &rows);
std::sort(rows.begin(), rows.en...
std::sort の中身
• 整列アルゴリズム
– クイックソート+挿入ソート
• クイックソートで絞り込み,挿入ソートで仕上げる

– ヒープソート
• クイックソートで効率が悪いときに使う

• 時間計算量
– O(n log n)

2...
実際にやってみた
• 環境
– プロセッサ:Core2 Duo U9600 1.6GHz
– コンパイラ:clang++-3.3

• データ
– 行数:1,000,000
– 値域:[ 0, 1,000,000]

• 結果
– 時間:0.2...
もっと速くするには
• ランダムアクセスを減らす
– ROWID とデータを組にして整列する
• std::vector<std::pair<RowID, Int64>>

• 値の重複を利用する
– 三分岐のクイックソートにする

• 整列範...
ランダムアクセスを減らす
• サンプルの実装
– 問題点
• Column の参照がランダムアクセスになる

• ROWID とデータを組にする
– 利点
• Column の参照がシーケンシャルアクセスになる

– 欠点
• 組にする手間がか...
さっそく試してみた
• 環境
– プロセッサ:Core2 Duo U9600 1.6GHz
– コンパイラ:clang++-3.3

• データ
– 行数:1,000,000
– 値域:[ 0, 1,000,000]

• 結果
– 改良前:0...
値の重複を利用する
• 通常のクイックソート
– 枢軸以下,枢軸,枢軸以上
• 枢軸の同値は左右のどちらかに入る
• ほぼ二分岐になる

• 三分岐のクイックソート
– 枢軸より小さい,枢軸と同じ,枢軸より大きい
• 値の重複が多ければ再帰が浅...
また試してみた
• データ
– 最大値:10, 100, …, 1,000,000
最大値 改良前 [秒] 改良後 [秒]
10
0.132
0.067
100
0.145
0.095
1,000
0.160
0.122
10,000
0.16...
整列範囲を利用する
• 全体ソート
– 全体を整列して上位 Limit 行を取り出す

• 部分ソート(クイックソート)
– 上位 Limit 行以外の整列を省略する
• クイックソートなら簡単に導入できる

2014年1月11日

カラムスト...
またまた試してみた
• 整列範囲
– Limit:10, 100, …, 1,000,000
Limit 改良前 [秒] 改良後 [秒]
10
0.212
0.036
100
0.213
0.036
1,000
0.212
0.036
10,0...
狭い整列範囲を利用する
• 部分ソート(挿入ソート)
– 手順
• 先頭の Limit 行を整列する
• 先頭の Limit 行が上位 Limit 行となるように
残りの行をひとつずつ挿入していく

– ポイント
• アクセスの局所性が高い
•...
比べてみた
• 整列範囲
– Limit:10, 100, …, 1,000,000
Limit クイックソート
[秒]
10
0.067
100
0.095
1,000
0.122
10,000
0.154
100,000
0.181
201...
まとめ
• 話した内容
– 基本はクイックソート
– データ・整列条件に応じた効率化
– 挿入ソートが大活躍

• 話さなかった内容
– 整列の安定・不安定
– 整列範囲の Offset
– 複数カラム対象の整列
– ヒープソートによる部分ソー...
Upcoming SlideShare
Loading in …5
×

カラムストアと整列(基礎)

1,604 views

Published on

カラムの値を基準として行 ID の一覧を整列する方法について,少しばかり調べてみたことを述べています.

Published in: Technology
0 Comments
4 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
1,604
On SlideShare
0
From Embeds
0
Number of Embeds
513
Actions
Shares
0
Downloads
16
Comments
0
Likes
4
Embeds 0
No embeds

No notes for slide

カラムストアと整列(基礎)

  1. 1. カラムストアと整列 矢田 晋 @s5yata 有限会社未来検索ブラジル
  2. 2. 自己紹介 • 所属 – 有限会社未来検索ブラジル • 仕事内容 – カラムストア+全文検索(Grnxx)の開発 • 公開物 – トライのライブラリ(darts-clone, marisa-trie) – 日本語 N-gram コーパス 2014年1月11日 カラムストアと整列 2
  3. 3. 発表内容 カラムストアの ORDER BY について (独断と偏見により) 検討&実験してみた 2014年1月11日 カラムストアと整列 3
  4. 4. カラムストアって何? • 縦に分割されているイメージ ROWID 1 ColumnA 100 ColumnB “Apple” ColumnC 1.73 2 3 … N–2 N–1 N 200 150 … 300 120 230 “Banana” “Orange” … “Melon” “Peach” “Lemon” 0.25 1.00 … 3.14 1.41 2.00 2014年1月11日 カラムストアと整列 4
  5. 5. カラムストアの検索 • 条件に該当する行の一覧を作成する – 例:ColumnA < 200 => { 1, 3, N – 1 } ROWID ColumnA ColumnB ColumnC 1 100 “Apple” 1.73 2 200 “Banana” 0.25 3 150 “Orange” 1.00 … … … … N–2 300 “Melon” 3.14 N–1 120 “Peach” 1.41 N 230 “Lemon” 2.00 2014年1月11日 カラムストアと整列 5
  6. 6. カラムストアの整列 • 行(ROWID)の一覧を整列する – 例:ORDER BY ColumnC => { 3, N – 1, 1 } ROWID ColumnA ColumnB ColumnC 1 100 “Apple” 1.73 2 200 “Banana” 0.25 3 150 “Orange” 1.00 … … … … N–2 300 “Melon” 3.14 N–1 120 “Peach” 1.41 N 230 “Lemon” 2.00 2014年1月11日 カラムストアと整列 6
  7. 7. 問題を単純化しよう • データ型 • 整列条件 – ROWID: UInt64 – Column: Int64 – 単一カラム – 昇順固定 • データ • 整列範囲 – 擬似乱数(mt19937) – 上位 Limit 行 • 行の一覧 – { 1, 2, 3, …, N – 1, N } 2014年1月11日 カラムストアと整列 7
  8. 8. サンプルコード std::vector<Int64> column; std::vector<RowID> rows; generate_data(&column, &rows); std::sort(rows.begin(), rows.end(), Comparer(column)); test_result (column, rows); ここの時間を 計測する 2014年1月11日 カラムストアと整列 8
  9. 9. std::sort の中身 • 整列アルゴリズム – クイックソート+挿入ソート • クイックソートで絞り込み,挿入ソートで仕上げる – ヒープソート • クイックソートで効率が悪いときに使う • 時間計算量 – O(n log n) 2014年1月11日 カラムストアと整列 9
  10. 10. 実際にやってみた • 環境 – プロセッサ:Core2 Duo U9600 1.6GHz – コンパイラ:clang++-3.3 • データ – 行数:1,000,000 – 値域:[ 0, 1,000,000] • 結果 – 時間:0.293 秒 2014年1月11日 ベースライン カラムストアと整列 10
  11. 11. もっと速くするには • ランダムアクセスを減らす – ROWID とデータを組にして整列する • std::vector<std::pair<RowID, Int64>> • 値の重複を利用する – 三分岐のクイックソートにする • 整列範囲を利用する – 部分ソートを使う 2014年1月11日 カラムストアと整列 11
  12. 12. ランダムアクセスを減らす • サンプルの実装 – 問題点 • Column の参照がランダムアクセスになる • ROWID とデータを組にする – 利点 • Column の参照がシーケンシャルアクセスになる – 欠点 • 組にする手間がかかる • 整列結果を書き戻す手間がかかる 2014年1月11日 カラムストアと整列 12
  13. 13. さっそく試してみた • 環境 – プロセッサ:Core2 Duo U9600 1.6GHz – コンパイラ:clang++-3.3 • データ – 行数:1,000,000 – 値域:[ 0, 1,000,000] • 結果 – 改良前:0.293 秒 – 改良後:0.192 秒 2014年1月11日 速くなった カラムストアと整列 13
  14. 14. 値の重複を利用する • 通常のクイックソート – 枢軸以下,枢軸,枢軸以上 • 枢軸の同値は左右のどちらかに入る • ほぼ二分岐になる • 三分岐のクイックソート – 枢軸より小さい,枢軸と同じ,枢軸より大きい • 値の重複が多ければ再帰が浅くなる • 値の種類が少なければ再帰が浅くなる 2014年1月11日 カラムストアと整列 14
  15. 15. また試してみた • データ – 最大値:10, 100, …, 1,000,000 最大値 改良前 [秒] 改良後 [秒] 10 0.132 0.067 100 0.145 0.095 1,000 0.160 0.122 10,000 0.165 0.154 100,000 0.186 0.181 1,000,000 0.192 0.212 2014年1月11日 カラムストアと整列 速くなった 遅くなった 15
  16. 16. 整列範囲を利用する • 全体ソート – 全体を整列して上位 Limit 行を取り出す • 部分ソート(クイックソート) – 上位 Limit 行以外の整列を省略する • クイックソートなら簡単に導入できる 2014年1月11日 カラムストアと整列 17
  17. 17. またまた試してみた • 整列範囲 – Limit:10, 100, …, 1,000,000 Limit 改良前 [秒] 改良後 [秒] 10 0.212 0.036 100 0.213 0.036 1,000 0.212 0.036 10,000 0.214 0.039 100,000 0.212 0.051 1,000,000 0.212 0.207 2014年1月11日 カラムストアと整列 速くなった 18
  18. 18. 狭い整列範囲を利用する • 部分ソート(挿入ソート) – 手順 • 先頭の Limit 行を整列する • 先頭の Limit 行が上位 Limit 行となるように 残りの行をひとつずつ挿入していく – ポイント • アクセスの局所性が高い • 平均時間計算量は O(n) になる 2014年1月11日 カラムストアと整列 19
  19. 19. 比べてみた • 整列範囲 – Limit:10, 100, …, 1,000,000 Limit クイックソート [秒] 10 0.067 100 0.095 1,000 0.122 10,000 0.154 100,000 0.181 2014年1月11日 挿入ソート [秒] 0.004 0.005 0.016 1.064 – カラムストアと整列 速くなった 遅くなった 20
  20. 20. まとめ • 話した内容 – 基本はクイックソート – データ・整列条件に応じた効率化 – 挿入ソートが大活躍 • 話さなかった内容 – 整列の安定・不安定 – 整列範囲の Offset – 複数カラム対象の整列 – ヒープソートによる部分ソート 2014年1月11日 カラムストアと整列 21

×