mysql索引以及查询优化

mysql 官方对索引的定义为:索引(Index)是帮助MySQL高效获取数据的数据结构。提取句子主干,就可以得到索引的本质:索引是数据结构。本文主要针对InnoDB进行讲解。

1. MySQL 如何使用索引

索引用于快速查找具有特定列值的行。如果没有索引,MySQL 必须从第一行开始,然后通读整个表以查找相关行。桌子越大,这个成本就越高。如果该表具有相关列的索引,MySQL 可以快速确定要在数据文件中间查找的位置,而无需查看所有数据。这比顺序读取每一行要快得多。

大多数 MySQL 索引(PRIMARY KEY、 UNIQUE、INDEX和 FULLTEXT)都存储在 B 树中。例外:空间数据类型的索引使用 R 树;MEMORY 表也​​支持哈希索引;InnoDB对FULLTEXT索引使用倒排列表。

2. 索引类型

2.1. 普通索引(INDEX)

普通索引是指MySQL中的基本索引类型,允许在定义索引的列中插入重复值和空值

2.2. 唯一索引(UNIQUE)

索引列的值必须唯一,但允许有空值。若是组合索引,则列值的组合必须唯一。主键索引是一种特殊的唯一索引,不允许有空值

2.3. 主键索引(PRIMARY KEY)(聚集索引)

InnoDB存储引擎的表会存在主键(唯一非null),如果建表的时候没有指定主键,则会使用第一非空的唯一索引作为聚集索引,否则InnoDB会自动帮你创建一个不可见的、长度为6字节的row_id用来作为聚集索引。

2.4. 组合索引

组合索引指在表的多个字段组合上创建的索引,只有在查询条件中使用了这些字段的左边字段时,索引才会被使用。使用组合索引时遵循最左前缀集合

2.5. 全文索引(FULLTEXT)

全文索引类型为FULLTEXT,在定义索引的列上支持值的全文查找,允许在这些索引列中插入重复值和空值。全文索引可以在CHAR、VARCHAR或者TEXT类型的列上创建

--创建索引
ALTER TABLE `table_name` ADD INDEX ( `column` )         --普通索引
ALTER TABLE `table_name` ADD UNIQUE (`column`)          --唯一索引
ALTER TABLE `table_name` ADD FULLTEXT (`column`)        --全文索引
ALTER TABLE `table_name` ADD PRIMARY KEY ( `column` )   --主键索引
ALTER TABLE `table_name` ADD INDEX index_name (`column1`,`column2`,`column3`)   --组合索引
ALTER TABLE `table_name` ADD UNIQUE index_name (`column1`,`column2`,`column3`)  --组合唯一索引

3. 聚集索引跟非聚集索引的区别

聚集索引是只主键创建的索引。非聚集索引就是除了主键以外的索引,简称二级索引。

3.1. 聚集索引

聚集索引表记录的排列顺序和索引的排列顺序保持一致,所以查询效率快。只要找到索引标志保证就找到了数据集。

聚集索引又分为有序、无序:这两种情况在效率上有一定的差距

有序:每次插入新的记录,记录就会顺序添加到当前索引节点的后续位置,当一页写满,就会自动开辟一个新的页

无序:由于每次插入主键的值近似于随机,因此每次新纪录都要被插到现有索引页得中间某个位置,此时MySQL不得不为了将新记录插到合适位置而移动数据,甚至目标页面可能已经被回写到磁盘上而从缓存中清掉,此时又要从磁盘上读回来,这增加了很多开销,同时频繁的移动、分页操作造成了大量的碎片,得到了不够紧凑的索引结构,后续不得不通过OPTIMIZE TABLE来重建表并优化填充页面。

3.2. 非聚集索引

非聚集索引定义了表中记录的一些逻辑顺序,但记录的物理和索引不一定保持一致,两种索引都采用B+树的结构,非聚集索引的叶子层并不和数据叶相互重叠,而是采用叶子层包含一个指向表中的记录指针。非聚集索引的缺点就是索引的层次比较多,但是不会造成数据的重排。