mysql优化面试整理-吊打面试官

1. MySQL有哪些存储引擎,各有什么特点

  • InnoDB
    MySQL5.5以后的默认引擎,支持行锁、事务和外键,并发写性能高,适合读写较多的业务场景。
  • MyISAM
    MySQL5.5之前的默认引擎,不支持行锁、事务和外键,支持表锁,并发写性能较低,访问速度较快。适合以读和插入为主的业务场景。不适合修改和删除较多的业务场景。
  • Memory
    数据存放在内存中,容易丢失数据。基本上用不到该引擎,可以用Redis等缓存中间件替代。

2. MySQL的索引结构

B+Tree

特点:所有的数据都存在叶子节点,并且相邻的叶子节点都有指针链接。

3. 索引分类

  • 聚集索引
    一般是主键,索引和数据存储在一起,叶子节点保存行数据。
    如果表没有主键,MySQL会以第一个唯一索引作为聚集索引。
    如果表也没有唯一索引,MySQL会自动创建一个rowId作为隐藏的聚集索引。
  • 非聚集索引
    我们手动创建的索引一般都是非聚集索引,索引和数据分开存储,叶子节点保存行对应的主键。

延申问题:加入一个表有主键Id,字段a、字段b、字段c组成,其中A和B建立了联合索引,那么select Id,a,b,c where a=‘1’,是否可以进行优化?
答:可以的,目前的方案由于a和b建立了索引,那么查询a的时候也能在索引中查询到b,而索引的叶子节点存储的是主键,那么Id也可以一次性查出来。而c字段没有索引,叶子节点也不会存储c字段,那么就需要根据叶子节点关联到的主键通过聚集索引去查询行数据,造成了回表查询。
优化方案就是:a、b、c一起建立联合索引,就可以一次查出id,a,b,c四个字段了,避免了回表查询。

4. 索引的设计原则

  1. 针对于数据量较大,且查询比较频繁的表建立索引。
  2. 针对于常作为查询条件(where)、排序(order by)、分组(group by)操作的字段建立索引。
  3. 尽量选择区分度高的列作为索引,尽量建立唯一索引,区分度越高,使用索引的效率越高。
  4. 如果是字符串类型的字段,字段的长度较长,可以针对于字段的特点,建立前缀索引。
  5. 尽量使用联合索引,减少单列索引,查询时,联合索引很多时候可以覆盖索引,节省存储空间,避免回表,提高查询效率。
  6. 要控制索引的数量,索引并不是多多益善,索引越多,维护索引结构的代价也就越大,会影响增删改的效率。
  7. 如果索引列不能存储NULL值,请在创建表时使用NOT NULL约束它。当优化器知道每列是否包含NULL值时,它可以更好地确定哪个索引最有效地用于查询。

5. 索引使用原则

最左前缀法则
指的是查询从索引的最左前列开始,并且不跳过中间的列。

避免索引失效
索引失效的几种情况:

  • 模糊查询%在前面
  • 在索引列上进行计算操作,比如截取字符串
  • 范围查询大于或小于,大于或小于右边的列索引会失效(可用大于等于或小于等于代替)
  • or链接的查询,or前后字段都要有索引,否则索引会失效
  • 字符串字段要使用引号,否则索引失效
  • 数据分布范围较小,索引可能失效(比如性别字段建立索引,90条是男10条是女,这时候可能不会用到索引)

覆盖索引
尽量使用覆盖索引, 覆盖索引就是只查询建立索引的字段,减少使用select * (逐渐查询除外),避免回表查询。

前缀索引
当字段类型为varchar、text等时,有时候需要索引很长的字符串,这会让索引变得很大,查询时,浪费大量的磁盘O,影响查询效率。此时可以只将字符串的一部分前缀,建立索引,这样可以大大节约索引空间,从而提高索引效率。

复合索引
尽量使用复合索引,少使用单列索引。如果a,b,c都只创建了单列索引,那么mysql只会选择最优的一个索引使用,而不会把三个字段的索引都用上。如果a,b,c创建了联合索引,那么他们三个字段都会用到索引去查询。

6. SQL性能分析

1. 慢查询日志
配置文件中开启慢查询日志,没有性能问题的话,可以不用开启,因为记录慢查询日志也是会耗费时间的。

##开启慢查询日志
slow_query_log=1

##设置慢查询日志时间为2秒,默认10秒,单位:秒
long_query_time=2

2. profile关键字
通过该关键字可以分析出,慢查询具体慢到哪里了。可能的原因有查询结果太大,内存不够用,需要借助磁盘空间、产生了临时表、复制内存中的临时表到磁盘、出现了锁等。

##假如这是一条慢查询sql
SELECT * FROM pms_sku_info WHERE sku_name LIKE '%Apple iPhone 13 (A2634) 星光色 128%';
##查看执行时间和Query_Id
show profiles;
##根据query_id具体分析时间花费在哪里了
show profile for query query_id;
##根据query_id查看sql的cpu使用情况
show profile cpu for query query_id;

3.explain关键字
通过该关键字可以分析sql执行的计划,在查询语句前加上该关键字即可。一些重要指标供参考分析,比如type字段可以看出sql的执行效率、possible_key列出可能会用到的索引、key列出实际用到的索引、rows扫描行数、filtered返回行数与读取行数的百分比等。

你可能感兴趣的:(面试专栏,mysql,面试,java)