【刷题Day04】MySQL索引与优化

MySQL 中的索引数量是否越多越好?为什么?

回答:不是,首先索引也会占据内存。另外数据库的增删改都需要对索引再进行维护,过多索引会消耗大量不必要的资源。

  • 优化答案的思路:
    • 性能需要从时间、空间为角度进行分析
    • 答题思路:计组 - B+树 - 应用,即底层逻辑、
      • 从时间上:索引在增删改时需要更新、B+树也有页分裂、合并等操作,应用时索引越多需要修改的地方越多。
      • 从空间上:索引占据内存、新建二级索引需要新建B+树,默认页大小16KB、应用时如果数据量大且索引多,会占很多空间。

补充

  • 时间
    • 增删改时,索引也必须更新,会增加写入操作的开销。
    • 如删除一个name为A的记录,不仅主键索引上需要修改如果name字段有索引,name索引也需要修改所以索引越多需要修改的地方也就越多,增加时间开销,同时B+树可能会有页分裂、合并等操作,时间开销就会更大。
  • 空间
    • 每建立一个二级索引,都需要新建一个B+树,默认每个数据页都是16KB,如果数据量很大,索引又很多,占用的空间会很大。

如何使用 MySQL 的 EXPLAIN 语句进行查询分析?

EXPLAIN SELECT … 即可对EXPLAIN后的查询语句进行分析

  • EXPLAIN的主要属性:
    • id:查询的执行顺序的标识符,值越大优先级越高。简单查询的id通常为1,复杂的id会有多个
    • select_type:查询的类型,如SIMPLE、PRIMARY(主查询)、SUBQUERY等
    • table:查询的表
    • type:访问类型
      性能从好到差的顺序是:const > eq_ref > ref > range(范围扫描) > index(索引扫描) > ALL(全表扫描)
      • system:查询的表只有一行(系统表),不常见
      • const:主键或唯一索引,并且是常量比较
      • eq_ref:对于每个来自前一张表的行,MySQL仅访问一次这个表。通常发生在连接查询中使用主键或唯一索引
      • ref:MySQL使用非唯一索引扫描来查找行。查询条件使用的索引是非唯一的(如普通索引)
      • range:MySQL会扫描表的一部分,而不是全部行。范围扫描通常出现在使用索引的范围查询
      • index:表示MySQL扫描索引中的所有行,而不是表中的所有行。即使索引列的值覆盖查询,也需要扫描整个索引
      • all(性能最差):MySQL需要扫描表的所有行,即全表扫描。通常发生在没有索引的查询
    • possible_keys:可能用到的索引
    • key:实际用到的索引
    • key_len:用到的索引的长度
    • ref:显示索引哪列被使用
    • rows:估计要扫描的行数,值越小越好
    • filtered:显示查询条件过滤掉的行的百分比,高百分比表示查询条件的选择性好
    • Extra:额外信息,如:
      • Using index:使用覆盖索引
      • Using where:使用WHERE条件进行过滤
      • Using temporary:使用临时表
      • Using filesort:需要额外排序步骤

MySQL 中如何进行 SQL 调优?

  • 主要通过观察慢SQL利用explain分析查询语句中的执行计划,识别性能瓶颈,优化查询语句。
    慢SQL:MySQL自带的日志记录,默认关闭,通过set global slow_query_log = 'ON'开启
    • 合理涉及索引,利用联合索引进行覆盖索引的优化,避免回表,减少一次查询和随机I/O
    • **避免SELECT ***,只查询必要的字段
    • 避免在SQL中进行函数计算等操作
    • 避免使用**%LIKE**导致全表扫描
    • 联合索引需满足最左匹配原则
    • 不要对无索引字段排序
    • 连表查询注意不同字段的字符集是否一致
  • 利用缓存优化,变化少或者访问频繁的数据设置到缓存中
  • 通过业务优化,少展示不必要的字段,减少多表查询的情况,将列表查询替换成分页分批查询等

你可能感兴趣的:(面试题,mysql,数据库)