数据库优化
主要从下面的角度来进行
硬件资源优化:增加机器配置
操作系统优化:调整OS的某些设置
服务器/引擎优化:比如调整事务隔离级别;调整InnoDB引擎的日志刷盘时机
SQL优化:针对SQL本身
SQL优化是最容易的一点优化,站在数据库的角度,SQL优化的目标是:
减少磁盘IO:尽量避免全表扫描、尽量使用索引、尽量使用覆盖索引
减少内存和CPU的消耗:尽量减少排序、分组和去重之类的操作
EXPLAIN命令
如果想知道优化后的效果,需要掌握一个工具,也就是EXPLAIN
命令。用法是EXPLAIN my_sql
,数据库就会返回一个执行计划。
比如select * from student where id = 1
执行计划比较关键的字段如下:
type
:查询到所需行需要的方式,从好到坏依次是system> const> eq_ref> ref> range> index> ALL
system/const
可以理解为数据库只会返回一行数据,查询时间是固定的eq_ref/ref
可以理解为根据索引的值来查找range
是索引范围扫描index
是索引全表扫描,扫描索引所在的B+树ALL
是全表扫描,如果表数据都在缓存就不需要磁盘IO
注意:索引的扫描里,索引如果不在缓存的话也需要磁盘IO。扫描二级索引比扫描全表(主键索引)的优势是二级索引一般只存储索引列和id,数据很小。性能从好到差分别是 根据主键取数据 > 根据普通索引取数据 > 索引全表扫描 > 全表扫描
possible_keys
:候选的索引key
:实际使用的索引rows
:扫描的行数filtered
:查找到所需要的数据占rows
的比例
设计索引列
外键:一般用于关联、过滤数据,正常来说都会为表的外键创建索引
频繁出现在
where
中的列,为了避免全表扫描频繁出现在
order by
的列,为了避免数据库在查询结构出来后再次排序频繁出现在关联查询的关联条件中的列。不过一般不建议使用关联查询
区分度很高的列。比如每一行数据都不同的列,并且创建联合索引的时候,区分度很高的列应该尽可能放在左边。(最左匹配原则)
数据量大的表更改表结构
修改索引的时候,数据量大的表和数据量小的表修改索引的实际方案不一样。因为修改索引相当于表定义的变更,核心问题是数据库会加表锁,直到修改完成。如果这个表的数据很多,在执行加索引的命令时,整张表可能会被锁住几分钟甚至几小时。
所以数据量大的表结构变更是一件很复杂的事情,一般可以考虑的方案有三种:
停机变更:把整个业务停止,更新表结构。或是只把跟这个表有关的功能下线,不需要把整个服务或系统下线。
业务低峰期变更
创建新表,数据迁移
面试相关
准备一些SQL优化的案例
维护的业务的所有表结构定义和索引定义,每个表上执行最频繁的三个SQL是否用到了索引
之前的慢SQL是怎么发现、分析和优化的,记住SQL优化前后的执行时间
深挖的一些方向
一些常见的问题 可以引导导SQL优化里
是否做过性能优化
接口的响应时间是多少 有没有优化的空间
是否了解索引、用过索引
基本思路
基本思路就是将SQL优化作为全方面优化系统性能的一个措施。
xx系统是一个核心系统,对可用性和性能都有很高的要求,可用性要求是xxxx,性能要求是平均RT控制在100ms内。做了很多性能优化的事情,比如SQL优化。
根据SQL慢查询监控 -> 排查SQL问题 -> 通过EXPLAIN命令查看SQL的执行计划,看看有没有走索引、走了哪些索引、是否有内存排序、去重等操作 -> 尝试优化,包括改写SQL、修改/创建索引
弄清楚数据库和数据库所在的OS的参数的含义和值