例如我们有表:
CREATE TABLE `my_tbl` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`id_type` int(11) NOT NULL,
`date` date NOT NULL,
`other_fields` varchar(200) CHARACTER SET latin1 NOT NULL,
PRIMARY KEY (`id`),
KEY `id_type` (`id_type`),
KEY `type_date` (`id_type`,`date`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8
Ther是两个索引: id_type 和 id_type,日期。
据我所知,如果我们有两个字段的索引,我们可以将它用作第一个字段的单个索引。
我可以删除索引 id_type 而不会损失性能吗?
更新:问这个问题引起注意,不同索引中的某个字段有时会有不同的基数。
答案 0 :(得分:2)
MySQL 5.7.9 - 删除 id_type 索引并没有什么区别。多列索引(type_date
)适用于两个查询。
解释查询输出:
mysql> explain SELECT id_type,date FROM my_tbl WHERE id_type='some';
+----+-------------+--------+------------+------+---------------+-----------+---------+-------+------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+--------+------------+------+---------------+-----------+---------+-------+------+----------+-------------+
| 1 | SIMPLE | my_tbl | NULL | ref | type_date | type_date | 4 | const | 1 | 100.00 | Using index |
+----+-------------+--------+------------+------+---------------+-----------+-----
mysql> explain SELECT id_type FROM my_tbl WHERE id_type='some';
+----+-------------+--------+------------+------+---------------+-----------+---------+-------+------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+--------+------------+------+---------------+-----------+---------+-------+------+----------+-------------+
| 1 | SIMPLE | my_tbl | NULL | ref | type_date | type_date | 4 | const | 1 | 100.00 | Using index |
+----+-------------+--------+------------+------+---------------+---------
mysql> show indexes from my_tbl;
+--------+------------+-----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+--------+------------+-----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| my_tbl | 0 | PRIMARY | 1 | id | A | 0 | NULL | NULL | | BTREE | | |
| my_tbl | 1 | type_date | 1 | id_type | A | 0 | NULL | NULL | | BTREE | | |
| my_tbl | 1 | type_date | 2 | date | A | 0 | NULL | NULL | | BTREE | | |
+--------+------------+-----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+-------------
答案 1 :(得分:1)
INDEX(a), INDEX(a, b)
- 删除前者,因为可以使用后者。
同时浪费磁盘空间并减慢插入(一点点)。
INDEX(a, c), INDEX(a, d)
- 你可能会发现这两个都很有用。
UNIQUE(a), INDEX(a, b)
- 现在,由于唯一性约束,前者是必需的。放弃后者。
另一方面 ... INDEX(a, b)
(在我的两个示例中)如果是“覆盖”索引,可能特别有用。也就是说,如果SELECT
触及 a
和b
以及否其他列。在这种情况下,查询完全在索引结构(BTree)中执行,而不必触及数据结构。