1

列ごとに個別のインデックスを作成するのではなく、複数の列に対して 1 つのインデックスを作成する必要があるのはどのような場合ですか?

4

3 に答える 3

2

複数の列を含む条件を持つクエリがある場合。すべての列フォーム条件をインデックスに追加する場合。実行を高速化します。コマンドを使用EXPLAINして、インデックスを追加する前後の実行計画を確認します。もちろん、あまり多くの列、特に異なる型の列を追加しないでください。インデックスを追加してもメリットがない可能性があるからです。

于 2012-11-25T17:29:41.050 に答える
0

どちらかまたは両方のケースである必要はありません。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が役立ちます。

于 2012-11-25T17:52:12.863 に答える
0

複合インデックスは、ほとんどのシナリオで役立ちます。以下のようなテーブルがある場合。

以下の表を検討してください。

ユーザー

+-----------+--------------+------+-----+---------+-------+
| 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 |
+----+-------------+-------+------+---------------+------+---------+------+------+-------------+

それでも範囲クエリとして実行されません。TIMESTAMPcolumnのみにインデックスを付けたためです。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 |
+----+-------------+-------+-------+---------------+------+---------+------+------+--------------------------+

今、それは範囲クエリとして実行され、検査された行の数を調べます。これは、指定された時間基準を超えるスキャンのみです。複合インデックスは、大きなテーブルに役立ちます。

于 2012-11-25T17:48:00.340 に答える