在哪种情况下,我应该为多列创建一个索引而不是为每列创建单独的索引?
答案 0 :(得分:2)
如果您的条件包含多列的查询。如果将所有列条件添加到索引中。你会加快执行速度。使用EXPLAIN
命令检查添加索引之前和之后的执行计划。当然,不要添加太多列,尤其是不同类型的列,因为添加索引没有任何好处。
答案 1 :(得分: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
执行。我们想要为TIMESTAMP
列创建索引。
在为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
列编制了索引。我们想要创建一个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 |
+----+-------------+-------+-------+---------------+------+---------+------+------+--------------------------+
现在,它作为范围查询执行,并查看检查的行数,它仅扫描超过给定时间条件。组合索引将有助于大型表格。
答案 2 :(得分:0)
它不一定是一个或两个案例。假设你有一个ORDERS表:
orderid integer,
orderdate date,
etc...
和ORDERDETAIL表
orderid integer,
lineno integer,
productID integer,
etc...
您可能需要orderdetail.orderid
上的索引,因为您将始终对此进行查找,并且DBMS将使用它来验证外键查找的引用完整性,返回{{1} }。但是,你可能最终会做很多选择:
orders
在这种情况下,select *
from orderdetail
where orderid=?
order by lineno
上的索引将是有益的。