1. 覆盖索引:通过索引查询的时候,不需要回表操作,即查询的字段在索引中存在。由于覆盖索引可以减少树的搜索次数,显著提升查询性能,所以使用覆盖索引是一个常用的性能优化手段。

**

  1. 最左前缀原则:索引项是按照索引定义里面出现的字段顺序排序的。基于这个特性,索引其实是可以复用的,即如果有(a,b)联合索引了,就不需要单独在a上建立索引。

  2. 索引下推:如果满足最左前缀原则的索引,搜索条件中包含不是左索引的字段,mysql会先判断满足搜索条件的索引,之后再回表找到其他字段进行判断。

DDL(Data Definition Languages)语句:即数据库定义语句,用来创建数据库中的表、索引、视图、存储过程、触发器等,常用的语句关键字有:CREATE,ALTER,DROP,TRUNCATE,COMMENT,RENAME。
DML(Data Manipulation Language)语句:即数据操纵语句,用来查询、添加、更新、删除等,常用的语句关键字有:SELECT,INSERT,UPDATE,DELETE,MERGE,CALL,EXPLAIN PLAN,LOCK TABLE,包括通用性的增删改查。

唯一索引和普通索引的区别

当需要更新一个数据页的时候,如果这个数据页在内存中,则直接更新。如果不在内存中,在不影响数据一致性的前提下,Innodb会将更新操作缓存在change buffer中,这样就不需要从磁盘中读入这个数据页。在下次查询需要访问这个数据页的时候,将数据页读入到内存,然后执行change buffer中与这个页有关的操作(这个过程称为merge),除了访问会触发merge,系统后台会定期merge,数据库正常关闭也会merge。

change buffer用的是buffer pool里的内存,因此不能无限增大。change buffer的大小,可以通过参数innodb_change_buffer_max_size来动态设置。这个参数设置为50的时候,表示change buffer的大小最多只能占用buffer pool的50%。

两者在查询效率上是相同的,但是再插入效率上,由于唯一索引需要将数据页读到内存中才能判断,所以就直接更新内存,而不适用change buffer。

mysql为什么会选错索引

在数据库里面,扫描行数是影响执行代价的因素之一。扫描的行数越少,意味着访问磁盘数据的次数越少,消耗的CPU资源越少。
当然,扫描行数并不是唯一的判断标准,优化器还会结合是否使用临时表、是否排序等因素进行综合判断。

扫描行数怎么判断

一个索引上,不同的值越多,这个索引的区分度就越好,而这个索引上不同值的个数,我们称为“基数”。
可以通过 show index from t 查看索引的基数:
image.png
基数是通过采样获取,既Innodb默认会采取N个页上索引的不同值,然后取平均数,然后乘以这个索引的页数,得到基数。当变更行超过1/M的时候,会自动触发一次索引统计

索引选错后的优化思路

1. 在查询语句里,指定索引

select from t *force index(a) where a between 1 and 100 and b between 300 and 400 order by b limit 1

2. 考虑修改语句,引导Innodb使用期望的索引

select from t *force index(a) where a between 1 and 100 and b between 300 and 400 order by b,a limit 1
之前索引选择 b,是因为使用索引b可以避免排序,因为索引本省就是有序的,只要遍历出来举行,所以即使扫描行数多,也判定为代价最小。
现在使用order by b, a, 则优化器认为b, a都要排序,那么扫描行成了最重要的选择条件,所以会选择扫描行数较少的 索引a。

3. 可以新增更适合的索引,让优化器做选择,或者删除误用的索引。

字符串怎么加索引

  1. 直接创完整索引,这样可能比较占空间,索引数据页可能会多个。
  2. 创建前缀索引,但是会增加扫描行数,并且不能使用覆盖索引。
  3. 倒叙存储,再创前缀索引,这种事为了应对像身份证那样的,前面都是相同的字符串
  4. 创建hash字段索引,查询性能稳定,有额外的存储和计算消耗,跟第三种方式一样,都不支持范围扫描。