インデックスありパターン
速くなった!
ALTER TABLE items ADD INDEX idx_item_id (item_id);
SQL
item_id 列のインデックスを作成するクエリ。
これによって item_id の索引が作成され、探したいデータへの
アクセスが効率的にできる。
Slide 22
Slide 22 text
スキャンしている
レコード量を確認
SHOW SESSION STATUS LIKE 'Handler_read%_next'
SQL
SQL が実際にどれくらいのレコード量をスキャンしているのかを確認
することができる。実際に、1行しか出力しないような SQL でも、裏
では大量のレコードを読んでいるとパフォーマンスが悪い。
インデックスを使うと探した
いレコードのみを読み込むの
で済んでいる
検証 SQL
force index() は指定インデックスを強制利用させる
分かりやすさのために使ってるだけで意味はない
インデックスありパターン
Slide 25
Slide 25 text
複合インデックス
Slide 26
Slide 26 text
複合インデックス
複数のカラムを合わせた索引
そのまんまだ
例えば 商品 No と メーカー名 を組み合わせて並び順を作れる
Slide 27
Slide 27 text
単体インデックス
B D
A B D E
C
C
RowID RowID RowID RowID
RowID
メーカー名 のみのインデックス例
ALTER TABLE テーブル ADD INDEX インデックス名 (メーカー名)
SQL
Slide 28
Slide 28 text
複合インデックス
メーカー名 と 商品 No の複合インデックス例
ALTER TABLE テーブル ADD INDEX インデックス名 (メーカー名, 商品No)
SQL
B, 02 D, 02
A, 03 B, 02 D, 02 E, 01
C, 01
C, 01
RowID RowID RowID RowID
RowID
複合インデックスは、指定したカラムの値を配列の
ような組み合わせ (タプル) で持っているようなもの
Slide 29
Slide 29 text
単体インデックスと
複合インデックスの相異
複合インデックス作成時に指定したカラムの並び順で作成される。この場合、メー
カー名→商品 No の順にインデックスを作成した。そのため、最初に指定したメー
カー名の単体インデックスと、同じような構造になっている。
複合インデックスが嬉しくなるのは、第一カラムが同一のレコード、この例だと同じ
メーカー名の色んな商品データが増えてから。
B D
A B D E
C
C
RowID RowID RowID RowID
RowID
B, 02 D, 02
A, 03 B, 02 D, 02 E, 01
C, 01
C, 01
RowID RowID RowID RowID
RowID
複合インデックスが使える例
SELECT * FROM 商品
WHERE メーカー名 = "A" AND 商品No = "03"
SQL
メーカー名と商品 No を指定しているので使える
SELECT * FROM 商品
WHERE メーカー名 = "A"
SQL
メーカー名だけでも、複合インデックスの
最初のカラムなので単体インデックスの代わりに使える
Slide 32
Slide 32 text
複合インデックスが使えない例
SELECT * FROM 商品
WHERE 商品No = "03"
SQL
複合インデックスの最初に指定したカラムがないと
インデックスは使えない
B, 02 D, 02
A, 03 B, 02 D, 02 E, 01
C, 01
C, 01
RowID RowID RowID RowID
RowID
メーカ名の A から E まで順に並べている
ので、全体から商品 No を効率的に探す
ことができない(結局、全データスキャ
ンになる)
03 どこに
あるの?
Slide 33
Slide 33 text
インデックスの誤解
Slide 34
Slide 34 text
NULL はインデックスが使えない
WHERE name IS NULL , IS NOT NULL は普通にインデックスが使える
NOT IN はインデックスが使えない
WHERE id NOT IN ( 1, 5, 10 ) は普通にインデックスが使える
否定形はインデックスが使えない
WHERE id != 100 などの否定でもインデックスは使える
ただ使ってもパフォーマンスが上がらないケースはある
WHERE の条件順は、インデックス指定順と同じにする必要がある
オプティマイザが自動で最適化してくれるので気にしなくて良い
WHERE name LIKE '%ru%'
誤解
誤解
誤解
誤解