Help us understand the problem. What is going on with this article?

インデックスが効いた検索をPHPで表してみた

More than 1 year has passed since last update.

はじめに

  • 「いんでっくす」を使って検索すると速いらしい
  • 「いんでっくす」を一切貼ってない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など色々あり、一概には上記の例は適用できません。

  • インデックスのイメージがわくこと
  • インデックスの重要性が分かること

が達成できたら嬉しく思います :smile:

Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away