今天的文章是之前筹划的《程序员十万个为什么》[1] 系列文章。
经常有面试题问到 MySQL not in 走索引吗?偶尔也会有同事说,千万别用 not in, 不走索引性能贼差,not in 性能好不好和对应的字段的区分度有关,那么这是真的吗?
今天小匠就带大家深入了解一下这个问题,首先我们需要使用 explain 关键字,所以需要了解一下这个关键字。explain 即为执行计划,可以输出某条 MySQL 语句的执行信息,以便让我们可以判断是否命中索引,是否需要优化。
文章提纲
explain 详解
索引原理
MySQL 语句查询原理
not in 原理
结论
首先我们创建一个表,插入一些数据以方便下文的测试。
CREATE TABLE test (
id INT NOT NULL AUTO_INCREMENT,
second_key INT,
text VARCHAR(100),
PRIMARY KEY (id),
KEY idx_second_key (second_key)
) Engine=InnoDB CHARSET=utf8;
INSERT INTO test VALUES
(1, 10, 't1'),
(2, 20, 't2'),
(3, 30, 't3'),
(4, 40, 't4'),
(5, 50, 't5'),
(6, 60, 't6'),
(7, 70, 't7'),
(8, 80, 't8');
运行 explain 命令我们得到如下内容
mysql> explain select * from test \G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: test
partitions: NULL
type: ALL
possible_keys: NULL
key: NULL
key_len: NULL
ref: NULL
rows: 13
filtered: 100.00
Extra: NULL
1 row in set, 1 warning (0.00 sec)
这里内容很多,但是值得我们关注的只有这几个字段
type
rows
Extra
下面我们逐一讲解下
type 表示 MySQL 在执行当前语句时候执行的类型,有这几个值 system,const,eq_ref,ref,fulltext,ref_or_null,index_merge,unique_subquery,index_subquery,range,index,ALL。
system 比较少见,当引擎是 MyISAM 或者 Memory 的时候并且只有一条记录,就是 system,表示可