Upgrade to Pro — share decks privately, control downloads, hide ads and more …

RDBのインデックス完全に理解する

Tada
October 29, 2024
46

 RDBのインデックス完全に理解する

RDBのインデックス完全に理解します

Tada

October 29, 2024
Tweet

Transcript

  1. RDBの仕組みその① • ある100万人いる巨大な表がある • 表をSQLで検索する • SELECT name WHERE name=’多田信洋’

    FROM Users • この時100万行全てを読まずに見つける方法は? ユーザー名 ユーザーID 多田 信洋 1 田中太郎 2 織田信長 3 … …
  2. いろいろと実験 • テーブルの説明 • 作成したテーブルは簡単な構造 • Idとnameとageのみの単純なテーブル • レコードは1000万件 •

    レコードの挿入は1万レコード2000msから2500ms程度 • インデックスをnameとageに作成した後では1万レコード3000msから 3500msほど
  3. 全件取得 • SELECT COUNT(*) FROM staffs; • 2.17s • CREATE

    INDEX age ON staffs; (年齢にインデックスを貼る) • 15.6s • もう一度SELECT COUNT(*) FROM staffs; • 2.04s
  4. Whereによる絞り込み age<10名レコードは100万件中9万件 • SELECT COUNT(*) FROM staffs WHERE age<10; (INDEXなし)

    • 2.09s • CREATE INDEX age ON staffs(age); • SELECT COUNT(*) FROM staffs WHERE age<10; • 0.28s • インデックスを貼ると早くなった
  5. LIKE句による比較 • SELECT COUNT(*) FROM staffs WHERE name LIKE ’a%’;

    • 2.045s • CREATE INDEX name ON staffs (name); (インデックスを貼る) • SELECT COUNT(*) FROM staffs WHERE name LIKE ’a%’; • 1.972s (効果なし!!) • CREATE INDEX name2 ON staffs (name text_pattern_ops); • SELECT COUNT(*) FROM staffs WHERE name LIKE ’a%’; • 0.198s ロケールの設定次第では前方一致にインデックスが効かない
  6. LIKE句を使った比較2 • SELECT COUNT(*) FROM staffs WHERE name LIKE ‘ab%cd’

    • これは’ab%’までの前方一致が効く 0.09s • SELECT COUNT(*) FROM staffs WHERE name LIKE ‘%cd’ • 後方一致には全く効果がない 2.04s
  7. EXPLAINの話 • EXPLAIN SELECT name FROM staffs WHERE age=50 ORDER

    BY name; • どのインデックスを使うか? • どのように実行をするつもりか?がわかる。 • 詳細は置いといて、costを比較すれば改善したかどうかがわかる
  8. 複合インデックス① • インデックス無し • EXPLAIN SELECT name FROM staffs WHERE

    age=50 ORDER BY name; • age=50 のものを探索 した後にソートしている。
  9. 複合インデックス② • ageにインデックスを貼った場合 • EXPLAIN SELECT name FROM staffs WHERE

    age=50 ORDER BY name; • age=50 のものをインデックスを用いて探索 した後にソートしている。 • Costは128993から77094に下がっている
  10. 複合インデックス③ • age,nameの順にインデックスを貼った場合 • EXPLAIN SELECT name FROM staffs WHERE

    age=50 ORDER BY name; • age=50 かつソート済みのものをインデックスを用いて探索 するだけ。 • Costは128993から30322に下がっている
  11. 軽い説明 • Nested Loop • JOIN時に1つ目のテーブルの各列に合わせて2つ目のテーブルを全捜査 • Bitmap Heap Scan

    • 動的にBitmapを構築してスキャン • Bitmap Index Scan • Indexを用いてBitmapスキャンする • OR演算など簡単でないクエリで使用
  12. やめた方がいいこと • カーディナリティの低い列にインデックスを貼る • 良かれと思って貼ったのに書き込みが遅くなるだけ • SQL中で演算を行う • SELECT *

    FROM staffs WHERE age*2=100; • ↑のように演算が入るとインデックスが効かない • 暗黙の型変換を行う • 上記の演算と同じ