为什么前缀索引比mysql中的索引慢?

时间:2017-10-11 03:24:12

标签: mysql indexing sql-optimization

表:(量:2100W)

CREATE TABLE `prefix` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `number` int(11) NOT NULL,
  `string` varchar(750) NOT NULL DEFAULT '',
  PRIMARY KEY (`id`),
  KEY `idx_string_prefix10` (`string`(10)),
  KEY `idx_string` (`string`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

歧视:

select count(distinct(left(string,10)))/count(*) from prefix;
+-------------------------------------------+
| count(distinct(left(string,10)))/count(*) |
+-------------------------------------------+
|                                    0.9999 |
+-------------------------------------------+

结果:

select sql_no_cache count(*) from prefix force index(idx_string_prefix10) 
where string <"1505d28b"
243.96s,241.88s

select sql_no_cache count(*) from prefix force index(idx_string) 
where string < "1505d28b"
7.96s,7.21s,7.53s

为什么前缀索引比mysql中的索引慢?(原谅我的英语不好)

explain select sql_no_cache count(*) from prefix force index(idx_string_prefix10) 
where string < "1505d28b";

+----+-------------+--------+------------+-------+---------------------+---------------------+---------+------+---------+----------+-------------+
| id | select_type |  table | partitions |  type |       possible_keys |                 key | key_len |  ref |    rows | filtered |       Extra |
+----+-------------+--------+------------+-------+---------------------+---------------------+---------+------+---------+----------+-------------+
|  1 |      SIMPLE | prefix |       NULL | range | idx_string_prefix10 | idx_string_prefix10 |      42 | NULL | 3489704 |   100.00 | Using where |
+----+-------------+--------+------------+-------+---------------------+---------------------+---------+------+---------+----------+-------------+

1 个答案:

答案 0 :(得分:0)

当你使用前缀索引时,MySQL必须从索引中读取,并且在读取索引之后,它也必须读取数据行,以确保WHERE条件选择该值。这是两次读取,并扫描了更多数据。

当你使用非前缀索引时,MySQL可以从索引中读取整个字符串值,并且它立即知道条件是否选择了值,或者是否可以跳过它。