はじめに
- 「いんでっくす」を使って検索すると速いらしい
- 「いんでっくす」を一切貼ってないDBを作ったら先輩に怒られた
- DB設計・クエリ実行において「いんでっくす」が重要らしい
という新人さんのために記事
ある程度プログラム書けるけどデータベース、特にインデックスはイマイチよく分からんという人のための記事
何となくインデックスを理解してもらうための記事
サンプルコード
まずインデックスなしの検索はこちら
クエリでいうとtype=all
no_index.php
<?php
<?php
// indexが貼られてない100000件のテストデータを用意
// [
// ['user_id' => 'user0', 'user_name' => 'user0_name'],
// ['user_id' => 'user1', 'user_name' => 'user1_name'],
// ...
// ]
$records = [];
for($i = 0; $i < 100000; $i++){
$records[] = ['user_id' => "user{$i}", 'user_name' => "user{$i}_name"];
}
// インデックスなし検索
// 例えばuser99999を探す
$time_start = microtime(true);
foreach($records as $record){
if($record['user_id'] === 'user99999'){
echo "user99999のユーザー名は{$record['user_name']}です\n";
break;
}
}
$time = microtime(true) - $time_start;
echo "{$time} 秒\n";
// user99999のユーザー名はuser99999_nameです
// 0.020262002944946 秒
次にインデックスあり検索
クエリでいうとtype=const
use_index.php
<?php
// user_idにインデックスが貼られてる100000件のテストデータを用意
// ['user0' => 'user0_name', 'user1' => 'user1_name', ...]
$records = [];
for($i = 0; $i < 100000; $i++){
$records['user'.$i] = 'user'.$i.'_name';
}
// インデックスあり検索
// 例えばuser99999を探す
$time_start = microtime(true);
echo "user99999のユーザー名は{$records['user99999']}です\n";
$time = microtime(true) - $time_start;
echo "{$time} 秒\n";
// user99999のユーザー名はuser99999_nameです
// 4.6014785766602E-5 秒
比較
インデックスなし | インデックスあり |
---|---|
0.02秒 | 0.000046秒 |
インデックスありの方が約434倍速いことが分かった
これは件数が多くなればなるほど顕著
解説
インデックスなしのパターンの方は配列に対して0から順に値の確認をしていき、該当のものがあれば値を取得して処理をやめます
値を順々に見ていくので当然レコード数が多くなればなるほど遅くなります
インデックスありのパターンの方は配列のキーがそのままインデックスなので順々に調べていかなくても1発で欲しい情報が取れています
なのでインデックスが効いた検索をした方が速いのです
またインデックスなしの例の方はテストデータの形がそもそもインデックスが貼られていない作りになっているため任意のユーザーのnameをとるのが難しい形になっています
これがインデックスを貼ってないDBというイメージです
インデックスありの例のように1発で取りたい情報が取れる形にデータ(DB)を作っておくのが望ましいですね
おわりに
実際のクエリのtypeにはconstの他にrefやrangeなど色々あり、一概には上記の例は適用できません。
- インデックスのイメージがわくこと
- インデックスの重要性が分かること
が達成できたら嬉しく思います