索引的好处,显而易见,就是可以快速定位数据,不需要全表扫描,提高查询性能。
索引的坏处,一个是体现在空间上,一个是体现在时间上。
空间上而言,你要是给很多的字段创建很多的索引,那必须创建很多颗B+树,每一颗B+树都是需要占用很多磁盘空间的。
时间上而言,会降低增删改的速度。在进行增删改的时候,每次都需要维护索引数据的有序性,无论是页内,还是页之间,如果没有了顺序,还需要进行数据页的挪动;或者是,不停的插入数据,会不断产生页分裂,这些都是耗费时间的!
至于如何才能使用最少的索引,满足最多的查询场景,还不至于影响到增删改的速度。这就是需要对索引进行设计了。
等值匹配规则:
最左匹配原则:
最左前缀匹配原则:
范围查找规则:
等值匹配 + 范围匹配规则:
Select * from table where xxx=xxx order by xxx,这样的一个SQL语句
在执行时:
尤其是对于这样的SQL: select * from table order by xx1,xx2,xx3 limit 100;
此时建立索引:Index(xx1,xx2,xx3),在这个联合索引中取出对应的100个id值,然后回表查询100条数据即可
注意:
Select count(*) from table group by xxx
在执行时:
Group by 后的字段,同样也是从最左侧字段开始,完美使用到索引的顺序性。根据排好序的数据,就可以快速执行后续操作了。
Order by 和group by 都是利用索引已经排好序的特性,进行磁盘顺序读,避免了针对杂乱无章的数据,利用临时磁盘加上部分内存进行耗时耗力的排序和分组。
覆盖索引不是一种索引,而是一种基于索引的查询方式。
覆盖索引的字段中就包含了所有要查询的字段,所以避免了回表操作,可以提高性能。
回表操作:在二级索引中查询到id列表之后,在根据id去聚簇索引中查询其他字段值。
注意:如果经过二级索引之后,找到的id数量过多,会导致大量的回表查询,在某些情况下还不如直接全表扫描。
先进行开发,开发结束之后,大概把所有可能用到的查询都写出来了,此时再进行索引设计。
总结看看所有查询中的where子句、order by 子句、group by 子句分别用到了哪些字段?哪些字段出现的频率较高?此时设计两三个索引,尽量把上面的字段都包含进去。然后再审视这些查询是否会真正使用到设计的索引。
字段基数问题,一般建立索引需要使用字段基数较大的字段,就是值比较多的字段,这样才能发挥出B+树的二分查找的优势来。对于varchar(255)类型的字段,需要选择一定长度的前缀来做前缀索引,需要权衡,既不能使索引占太大空间,又不能降低字段基数。
在插入时,会去维护聚簇索引、二级索引。由于插入的数据不一定是有序的,所以可能会导致索引树中某个数据页会自动分裂,这个分裂的过程就很耗时。对于主键来说,一定要使用自增主键,如果使用UUID作为主键,那么会导致聚簇索引频繁地进行页分裂。
Mysql内部架构_jerry_dyy的博客-CSDN博客
Mysql存储模型_jerry_dyy的博客-CSDN博客
InnoDB内部架构_jerry_dyy的博客-CSDN博客
Buffer Pool 核心原理_jerry_dyy的博客-CSDN博客
Buffer Pool生产实践_jerry_dyy的博客-CSDN博客
Mysql事务隔离机制_jerry_dyy的博客-CSDN博客
Mysql的锁机制_jerry_dyy的博客-CSDN博客
Mysql的索引深度讲解_jerry_dyy的博客-CSDN博客
Mysql索引的使用_jerry_dyy的博客-CSDN博客
SQL语句的执行计划_jerry_dyy的博客-CSDN博客_sql语句的执行计划