数据库
首页 > 数据库> > 20200129 3. MySQL 索引原理 - 拉勾教育

20200129 3. MySQL 索引原理 - 拉勾教育

作者:互联网

MySQL 索引原理

索引类型

索引可以提升查询速度,会影响 where 查询,以及 order by 排序。MySQL 索引类型如下:

普通索引

这是最基本的索引类型,基于普通字段建立的索引,没有任何限制。

创建普通索引的方法如下:

CREATE INDEX <索引的名字> ON tablename (字段名);
ALTER TABLE tablename ADD INDEX [索引的名字] (字段名);
CREATE TABLE tablename ( [...], INDEX [索引的名字] (字段名) );  

唯一索引

与"普通索引"类似,不同的就是:索引字段的值必须唯一,但 允许有空值 。在创建或修改表时追加唯一约束,就会自动创建对应的唯一索引。

创建唯一索引的方法如下:

CREATE UNIQUE INDEX <索引的名字> ON tablename (字段名);
ALTER TABLE tablename ADD UNIQUE INDEX [索引的名字] (字段名);
CREATE TABLE tablename ( [...], UNIQUE [索引的名字] (字段名) ;  

主键索引

它是一种特殊的唯一索引,不允许有空值。在创建或修改表时追加主键约束即可,每个表只能有一个主键。

创建主键索引的方法如下:

CREATE TABLE tablename ( [...], PRIMARY KEY (字段名) );
ALTER TABLE tablename ADD PRIMARY KEY (字段名);  

复合索引

单一索引是指索引列为一列的情况,即新建索引的语句只实施在一列上;用户可以在多个列上建立索引,这种索引叫做组复合索引(组合索引)。复合索引可以代替多个单一索引,相比多个单一索引复合索引所需的开销更小。

索引同时有两个概念叫做窄索引宽索引,窄索引是指索引列为1-2列的索引,宽索引也就是索引列超过2列的索引,设计索引的一个重要原则就是能用窄索引不用宽索引,因为窄索引往往比组合索引更有效。

创建组合索引的方法如下:

CREATE INDEX <索引的名字> ON tablename (字段名1,字段名2...);
ALTER TABLE tablename ADD INDEX [索引的名字] (字段名1,字段名2...);
CREATE TABLE tablename ( [...], INDEX [索引的名字] (字段名1,字段名2...) );

复合索引使用注意事项:

全文索引

查询操作在数据量比较少时,可以使用 like 模糊查询,但是对于大量的文本数据检索,效率很低。如果使用全文索引,查询速度会比 like 快很多倍。在MySQL 5.6 以前的版本,只有 MyISAM 存储引擎支持全文索引,从 MySQL 5.6 开始 MyISAM 和 InnoDB 存储引擎均支持。

创建全文索引的方法如下:

CREATE FULLTEXT INDEX <索引的名字> ON tablename (字段名);
ALTER TABLE tablename ADD FULLTEXT [索引的名字] (字段名);
CREATE TABLE tablename ( [...], FULLTEXT KEY [索引的名字] (字段名) ;

和常用的 like 模糊查询不同,全文索引有自己的语法格式,使用 matchagainst 关键字,比如:

select * from user
where match(name) against('aaa');

全文索引使用注意事项:

索引原理

MySQL官方对索引定义:是存储引擎用于快速查找记录的一种数据结构。需要额外开辟空间和数据维护工作。

索引涉及的理论知识:二分查找法、Hash 和 B+Tree

Hash 结构

B+Tree 结构

B-Tree 结构

B+Tree结构

相比 B 树,B+ 树进行范围查找时,只需要查找定位两个节点的索引值,然后利用叶子节点的指针进行遍历即可。而 B 树需要遍历范围内所有的节点和数据,显然 B+Tree 效率高。

聚簇索引和辅助索引

聚簇索引和非聚簇索引:B+Tree 的叶子节点存放主键索引值和行记录就属于聚簇索引;如果索引值和行记录分开存放就属于非聚簇索引。

主键索引和辅助索引:B+Tree 的叶子节点存放的是主键字段值就属于主键索引;如果存放的是非主键值就属于辅助索引(二级索引)。

在 InnoDB 引擎中,主键索引采用的就是聚簇索引结构存储。

索引分析与优化

EXPLAIN

MySQL 提供了一个 EXPLAIN 命令,它可以对 SELECT 语句进行分析,并输出 SELECT 执行的详细信息,供开发人员有针对性的优化。例如:

EXPLAIN 命令的输出内容大致如下:

mysql> EXPLAIN SELECT * from user\G;
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: user
   partitions: NULL
         type: ALL
possible_keys: NULL
          key: NULL
      key_len: NULL
          ref: NULL
         rows: 3
     filtered: 100.00
        Extra: NULL
1 row in set, 1 warning (0.00 sec) 

回表查询

在之前介绍过, InnoDB 索引有聚簇索引和辅助索引。聚簇索引的叶子节点存储行记录, InnoDB 必须要有,且只有一个。辅助索引的叶子节点存储的是主键值和索引字段值,通过辅助索引无法直接定位行记录,通常情况下,需要扫码两遍索引树。先通过辅助索引定位主键值,然后再通过聚簇索引定位行记录,这就叫做回表查询,它的性能比扫一遍索引树低。

总结:通过索引查询主键值,然后再去聚簇索引查询记录信息

覆盖索引

最左前缀原则

复合索引使用时遵循最左前缀原则,最左前缀顾名思义,就是最左优先,即查询中使用到最左边的列,那么查询就会使用到索引,如果从索引的第二列开始查找,索引将失效。

img

LIKE 查询

面试题:MySQL 在使用 like 模糊查询时,索引能不能起作用?

回答:MySQL在使用Like模糊查询时,索引是可以被使用的,只有把 % 字符写在后面才会使用到索引

select * from user where name like '%o%'; 	//不起作用
select * from user where name like 'o%'; 	//起作用
select * from user where name like '%o'; 	//不起作用  

NULL 查询

面试题:如果 MySQL 表的某一列含有 NULL 值,那么包含该列的索引是否有效?

对 MySQL 来说, NULL 是一个特殊的值,从概念上讲, NULL 意味着“一个未知值”,它的处理方式与其他值有些不同。比如:不能使用 =,<,> 这样的运算符,对 NULL 做算术运算的结果都是 NULL , count 时不会包括 NULL 行等, NULL 比空字符串需要更多的存储空间等。

NULL 列需要增加额外空间来记录其值是否为 NULL 。对于 MyISAM 表,每一个空列额外占用一位,四舍五入到最接近的字节。

虽然 MySQL 可以在含有 NULL 的列上使用索引,但 NULL 和其他数据还是有区别的,不建议列上允许为 NULL 。最好设置 NOT NULL ,并给一个默认值,比如 0 或空字符串等,如果是 datetime 类型,也可以设置系统当前时间或某个固定的特殊值,例如 '1970-01-01 00:00:00' 。

索引与排序

MySQL 查询支持 filesortindex 两种方式的排序, filesort 是先把结果查出,然后在缓存或磁盘进行排序操作,效率较低。使用 index 是指利用索引自动实现排序,不需另做排序操作,效率会比较高。

filesort 有两种排序算法:双路排序和单路排序。

如果我们 Explain 分析 SQL ,结果中 Extra 属性显示 Using filesort ,表示使用了 filesort 排序方式,需要优化。如果 Extra 属性显示 Using index 时,表示覆盖索引,也表示所有操作在索引上完成,也可以使用 index 排序方式,建议大家尽可能采用覆盖索引。

查询优化

慢查询定位

慢查询优化

分页查询优化

标签:name,拉勾,查询,索引,20200129,user,MySQL,NULL,select
来源: https://www.cnblogs.com/huangwenjie/p/14346322.html