列ごとに個別のインデックスを作成するのではなく、複数の列に対して 1 つのインデックスを作成する必要があるのはどのような場合ですか?
3 に答える
複数の列を含む条件を持つクエリがある場合。すべての列フォーム条件をインデックスに追加する場合。実行を高速化します。コマンドを使用EXPLAIN
して、インデックスを追加する前後の実行計画を確認します。もちろん、あまり多くの列、特に異なる型の列を追加しないでください。インデックスを追加してもメリットがない可能性があるからです。
どちらかまたは両方のケースである必要はありません。ORDERS テーブルがあるとします。
orderid integer,
orderdate date,
etc...
および ORDERDETAIL テーブル
orderid integer,
lineno integer,
productID integer,
etc...
常にインデックスを参照するため、おそらくインデックスが必要になるでしょうorderdetail.orderid
。DBMS は、外部キー ルックアップの参照整合性を検証するためにインデックスを使用しますorders
。ただし、次のような多くの選択を行うことになるでしょう。
select *
from orderdetail
where orderid=?
order by lineno
その場合は、上のインデックスorderdetail.orderid,orderdetail.lineno
が役立ちます。
複合インデックスは、ほとんどのシナリオで役立ちます。以下のようなテーブルがある場合。
以下の表を検討してください。
ユーザー
+-----------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-----------+--------------+------+-----+---------+-------+
| ID | int(11) | YES | | NULL | |
| USER | varchar(100) | YES | | NULL | |
| EMAIL_ID | varchar(200) | YES | | NULL | |
| MODE | varchar(50) | YES | | NULL | |
| TIMESTAMP | bigint(20) | YES | | NULL | |
+-----------+--------------+------+-----+---------+-------+
このテーブルでは、「SIGNIN」、「SIGNUP」、「CLOSE」などのユーザー アクションを監査しています。この場合、このテーブルから詳細をより迅速に取得したいと考えています。しかし、これには何百万ものエントリがあります。
私のテーブルの値。
select * from Users;
+------+----------+-----------------------+--------+---------------+
| ID | USER | EMAIL_ID | MODE | TIMESTAMP |
+------+----------+-----------------------+--------+---------------+
| 1 | kannan | kannanrbk.r@gmail.com | SIGNIN | 1353864896000 |
| 2 | bharathi | bharathikannan.r | SIGNUP | 1353864934000 |
| 2 | mack | mack@gmail.com | SIGNIN | 1353865121000 |
| 2 | david | david@gmail.com | SIGNIN | 1353865130000 |
+------+----------+-----------------------+--------+---------------+
クエリ:
select EMAIL_ID from Users where TIMESTAMP > 1353864896000;
出力の説明:
+----+-------------+-------+------+---------------+------+---------+------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+------+---------------+------+---------+------+------+-------------+
| 1 | SIMPLE | Users | ALL | NULL | NULL | NULL | NULL | 4 | Using where |
+----+-------------+-------+------+---------------+------+---------+------+------+-------------+
説明出力を見てください
テーブル内の行全体を調べます。なぜなら、このクエリは単体では実行されないからrange
です。columnのインデックスを作成しTIMESTAMP
ます。
タイムスタンプ列のインデックスを作成した後の出力について説明します。
+----+-------------+-------+------+---------------+------+---------+------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+------+---------------+------+---------+------+------+-------------+
| 1 | SIMPLE | Users | ALL | t_dx | NULL | NULL | NULL | 4 | Using where |
+----+-------------+-------+------+---------------+------+---------+------+------+-------------+
それでも範囲クエリとして実行されません。TIMESTAMP
columnのみにインデックスを付けたためです。TIMESTAMP,EMAIL_ID
このクエリを範囲 1 として実行するために、結合インデックスを作成します。
create index t_dx on Users(TIMESTAMP,EMAIL_ID);
結合索引を作成した後の出力について説明します。
+----+-------------+-------+-------+---------------+------+---------+------+------+--------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+-------+---------------+------+---------+------+------+--------------------------+
| 1 | SIMPLE | Users | range | t_dx | t_dx | 9 | NULL | 3 | Using where; Using index |
+----+-------------+-------+-------+---------------+------+---------+------+------+--------------------------+
今、それは範囲クエリとして実行され、検査された行の数を調べます。これは、指定された時間基準を超えるスキャンのみです。複合インデックスは、大きなテーブルに役立ちます。