有下表
CREATE TABLE `MCA_calls` (
`date_time_created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`call_id` bigint(20) unsigned NOT NULL,
`calling_number` bigint(20) unsigned NOT NULL,
`called_number` bigint(20) unsigned NOT NULL,
PRIMARY KEY (`call_id`,`calling_number`,`called_number`) USING BTREE,
KEY `date_time_created` (`date_time_created`),
KEY `called_number` (`called_number`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC;
我EXPLAIN在一个类型请求上做,我看到索引没有拉上来,如果我在字段上挂一个常规索引,called_number那么一切都好
mysql> EXPLAIN DELETE FROM MCA_calls WHERE called_number = 123456789;
+----+-------------+--------------------+------------+------+---------------+------+---------+------+--------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+--------------------+------------+------+---------------+------+---------+------+--------+----------+-------------+
| 1 | DELETE | MCA_calls | NULL | ALL | NULL | NULL | NULL | NULL | 192014 | 100.00 | Using where |
+----+-------------+--------------------+------------+------+---------------+------+---------+------+--------+----------+-------------+
索引就像一个排序的字典,假设您按姓氏然后按名字(在每个姓氏内部)对电话簿进行排序,现在您正试图找到所有“Oleg”。您必须滚动浏览所有内容。但是,如果他们首先按姓氏搜索“Ivanov”,那么他们会很快找到正确的页面,并且在其中他们已经找到了 Oleg Ivanovs。数据库与索引完全一样,它是索引中按体积计算的第一个字段,应该首先搜索。
因此,如果您最常查找它,则需要将 called_number 作为索引中的第一个字段。
我们还考虑按出生年份和姓氏排序的目录的情况。在搜索年份范围时,我们正在寻找从 1980 年到 1990 年出生的 Ivanovs。如果首先是年份,我们将不得不依次打开每年的页面并在那里寻找 Ivanov 块。因此,如果存在范围搜索的字段,最好将它们放在靠近键的末尾,并将具有精确匹配搜索的字段放在第一位。