1.索引是什么
索引是提高数据库查询性能的一种优化技术,MySQL索引采用B+Tree结构存储。
2.索引种类
-
普通索引:加速查询,无约束
-
唯一索引:列值唯一(可以有一个null值)
-
主键索引:列值唯一(不可以有null)+ 表中只有一个
-
组合索引:多列值组成一个索引
-
全文索引:对文本的内容进行分词,进行搜索
3.索引有哪些组成
- 索引键值(列值)
- 完整数据磁盘地址(一行数据记录地址)
- 子树节点间引用地址(指针)
注:Innodb加载默认磁盘大小(磁盘块)page默认16kb=16384bytes
4.MySQL为什么使用B+Tree
为了知道MySQL为什么使用B+Tree结构存储,我们了解以下几种树形数据结构
- 二叉查找树(BST)
左子树节点比根节点小,右子树节点比跟节点大,数据越多,查询越耗时O(N),二叉查找树左右会不平衡,如跟节点为2,只会在右节点增加。
-
平衡二叉树(AVL Tree):左右子树节点深度差绝对值不会超过1,会自动调整根节点(左旋或右旋),保证平衡。解决了二叉查找树不平衡的问题。但是存在浪费磁盘空间问题,因为innodb存储引擎每个子树节点会分配一个默认16kb的磁盘块,另外新增性能会受影响。
-
多路平衡查找树(Balanced Tree B Tree) B Tree:分裂和合并来保证B树平衡,节点会存储多个索引键,子树节点数量为根节点+1。B Tree解决了平衡二叉树存储一个键值带来的磁盘空间浪费。
-
加强版多路平衡查找树B+ Tree:叶子节点才存储数据,需要走到叶子节点才能查找数据,叶子节点page数据是有序的链表,有多少键值就有多少子树,1:1对应。
-
注:节点拥有的子树数量称为度(Degree)
5.B+Tree特点
- 减少树的深度和IO、减少磁盘存储空间。
- 查询更快(因为数据都放到叶子节点,叶子节点有指针链接相邻数据,避免从头扫描)
- 排序更快(因为叶子节点数据有指向相邻数据指针,有序链表)
6.计算存储数量
索引字段类型: Bigint =8 bytes
指针(子树节点引用地址): 6 bytes
完整数据记录例如:1kb
根节点磁盘单元数 * 子树数量 * 叶子节点完整数据条数(默认16kb,需计算每一条大概多少kb)=存储数量
如:1170(根磁盘块单元数量)*1170(子树磁盘块单元数量)*16(完整数据条数)=21902400存储数量
7.聚集索引和非聚集索引区别
聚集索引:叶子节点存储的是完整数据,数据存储有序
非聚集索引:叶子节点存储的是聚集索引的键值,需要根据聚集索引的键值去聚集索引中查找,这种方式称为“回表”
注:如果在一个表中没有创建聚集索引MySQL会先查找是否有唯一且不为空作为聚集索引,如果没有会自动生成一列“RowID”作为聚集索引
8.SQL语句注意事项
- 列的离散度低(重复值多)不需要建索引,建索引可能会失效,会被MySQL优化器自动优化,因为使用索引查找扫描数据会比较多,因为很多相同数据,MySQL优化器发现使用索引查找比不使用索引查找更耗时就会不使用索引查找,离散度如果大于80%可以创建索引。
列的离散度公式:count(distinct(column_name))/count(*)
- 联合索引最左匹配原则,查询条件不能缺少建索引时的左边字段,否则索引会失效
- 不要使用select * ,因为会导致回表操作,如果select字段是有建索引则直接返回索引数据,这种方式成为“覆盖索引”,可以减少回表操作
-
使用like %%查询的使用全文索引,使用其它索引会失效,因为索引是从左开始匹配的
-
频繁修改的列不要键索引,会影响更新性能
-
不要在条件列中计算或使用函数
-
表连接最好不要超过3张表,字段数据类型必须一致
-
单表索引建议控制在5个以内
-
联合索引最左匹配原则,查询条件不能缺少建索引时的左边字段,否则索引失效
9.如何查看是否有使用索引
Explain select * from ‘tb’ where name=’aa’
字段说明:
rows=查询扫描数量
key=不为空表示使用了索引
Extra=Using index 表示使用了覆盖索引