MySQL读写比例一般是10:1,大部分性能瓶颈在查询,所有优化性能的关键点都在查询,而索引可以有效的提升MySQL的查询性能。
索引通过特殊的数据结构和查询方式,能有效减少查询范围,减少IO的参数,从而提升查询效率
数据库索引本质上是一种数据结构(存储结构+算法),目的是为了加快搜索性能
以InnoDb引擎为例,主要支持三种数据结构,B+树、哈希索引、R树:
哈希索引:
实现原理:由索引列来决定存储位置。
优点:检索效率非常高,索引的检索可以一次到位,复杂度为O(1)
缺点:
1.索引无序,无法进行范围查询,只能用作IN,==等查询;无法排序
2.每次都要全表扫描
3.不符合最左缀原则,不能用部分索引建来搜索
4.当哈希值大量重复且数据量非常大时,由于哈希碰撞,查询效率会很低
B+树索引:
实现原理:参考【一文读懂】二叉树,平衡二叉树(AVL),红黑树,B+树的原理
优点:
1.与B-Tree比较,内节点不存储data只存储Key,叶子结点不存储指针,在大数据量情况下,能有效的减少IO次数
2.B+树的查询必须最终找到叶子节点,而B-树只需要找到匹配的元素即可,无论匹配元素是中间节点还是叶子节点。
因此B-树的查找性能不稳定(最好情况是只查根节点,最坏查到叶子节点),而B+树每次查找都是稳定点
3.B-树只能依靠繁琐的中序遍历,而B+树只需要在链表上遍历即可。范围查询更方便
4.B更充分利用磁盘预读
缺点:
精确查询效率不如哈希索引
R树索引:空间索引适用。
在MySQL中,不同存储引擎对索引的实现方式是不同的,引擎主要有MyISAM(图1)和InnoDB(图2)两种
聚集索引:一种索引,该索引中键值的逻辑顺序决定了表中相应行的物理顺序。
非聚集索引:一种索引,该索引中索引的逻辑顺序与磁盘上行的物理存储顺序不同。
相同点:
不同点:
图1 MyIASM主索引(左)和辅助索引(右)
图2 InnoDB主索引(左)和辅助索引(右)
在select语句之前加入explain关键字,通过查看type字段可以确定是否使用索引(为All表示未使用索引),possible_keys列出所有可能使用的索引,key是优化器选择后真正使用的索引
type 常用的类型有: ALL、index、range、 ref、eq_ref、const、system、NULL(从左到右,性能从差到好)
ALL:Full Table Scan, MySQL将遍历全表以找到匹配的行
index: Full Index Scan,index与ALL区别为index类型只遍历索引树
range:只检索给定范围的行,使用一个索引来选择行
ref: 表示上述表的连接匹配条件,即哪些列或常量被用于查找索引列上的值
eq_ref: 类似ref,区别就在使用的索引是唯一索引,对于每个索引键值,表中只有一条记录匹配,简单来说,就是多表连接中使用primary key或者 unique key作为关联条件
const、system: 当MySQL对查询某部分进行优化,并转换为一个常量时,使用这些类型访问。如将主键置于where列表中,MySQL就能将该查询转换为一个常量,system是const类型的特例,当查询的表只有一行的情况下,使用system
NULL: MySQL在优化过程中分解语句,执行时甚至不用访问表或索引,例如从一个索引列里选取最小值可以通过单独索引查找完成。
采用查询优化器
select * from table_name where key1 like '%a'
;该查询即使key1上存在索引,也不会被使用。索引创建:
利用覆盖索引来进行查询操作,避免回表。比如下面语句,可以建立索引(a,b,c)覆盖索引(所有数据都在索引里面),避免回表。select id, a from table where b=? and c=?
如果有 order by,可以建立联合索引,将order by的字段放在联合索引最后(防止file_sort的情况,影响性能)
业务上具有唯一特性的字段,必须建成唯一索引。
单表索引建议控制在5个以内,单索引字段数不允许超过5个。
尽量使用数字型字段,若只含数值信息的字段尽量不要设计为字符型,这会降低查询和连接的性能,并会增加存储开销。这是因为引擎在处理查询和连接时会逐个比较字符串中每一个字符,而对于数字型而言只需要比较一次就够了。
索引使用:
in 和 not in 也要慎用,多值查询一般是走索引的。但能用 between 就不要用 in,也可以考虑用exists代替。
不要在SQL操作中计算
SQL 性能优化 explain 中的 type:至少要达到 range 级别,要求是 ref 级别,如果可以是 consts 最好。
索引口诀:
全值匹配我最爱,最左前缀要遵守;
带头大哥不能死,中间兄弟不能断;
索引列上少计算,范围之后全失效;
LIKE百分写最右,覆盖索引不写星;
不等空值还有or,索引失效要少用。
https://www.cnblogs.com/developer_chan/p/9223671.html