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一个查询来执行的。我们要为TIMESTAMPcolumn 创建索引。

解释为时间戳列创建索引后的输出。

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

它仍然没有作为 range query 执行。因为我们只索引了TIMESTAMPcolumn 。我们想创建一个组合索引TIMESTAMP,EMAIL_ID来执行这个查询作为范围一。

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 回答