7、MySQL 优化
7.优化
7.0 MySQL优化
建表优化
尽量使用数字型字段,因为查询和链接时,只需比较一次,效率更快
尽量使用varchar少使用char,变长字段空间少,更省空间
对于区分度较低的索引,也就是有大量重复的索引,我们可以对其删除。
查询优化
少使用select * 语句
尽量少使用模糊查询 %a
不使用 not in ,in,这样会导致走全表索引
不实用 a or b 方式进行查询,会使其不走索引
尽量少使用子查询(因为需要创建临时表,还需要删除临时表)
索引优化
不要创建太多索引,多使用组合索引
对经常 order by 的语句创建索引
7.1 explain详解
列名 | 描述 |
---|---|
id | 在一个大的查询语句中每个SELECT 关键字都对应一个唯一的id |
select_type | SELECT 关键字对应的那个查询的类型 |
table | 表名 |
partitions | 匹配的分区信息 |
type | 针对单表的访问方法 |
possible_keys | 可能用到的索引 |
key | 实际上使用的索引 |
key_len | 实际使用到的索引长度 |
ref | 当使用索引列等值查询时,与索引列进行等值匹配的对象信息 |
rows | 预估的需要读取的记录条数 |
filtered | 某个表经过搜索条件过滤后剩余记录条数的百分比 |
Extra | 一些额外的信息 |
id:一个select一个id,对于连接查询来说他们只有一个 select 但是因为需要使用两个表,所以会出现两行数据,但是是相同id。另外优化器会对子查询进行重写,将子查询变成连接查询,所以我们只需要看有几个id就可以判断是否进行了重写。
如果id 为null则是创建的临时表。
推荐阅读:https://juejin.cn/post/6905232255937937415
7.2 MySQL慢查询优化
先来说一下MySQL慢查询
MySQL的慢查询,全名是慢查询日志 ,是MySQL中提供的一种日志记录,用来记录响应时间超过
(等于的不会记录下来)阈值的SQL语句。
设定值为long_query_time = 10,则会记录运行时间超过 10 秒的执行语句。
需要手动开启
有可能导致慢查询的原因
- 索引未设计好
可以现在备库上执行
- 查询语句没有写好
优化查询语句,有可能出现,没有命中索引的情况
- 选错索引
此时我们使用 force index 命令,强制使用索引
- 脏页问题
另一种还是我们上边所提到的刷脏页情况,只不过和写操作不同的是,是在读时候进行刷脏页的。
是不是有点懵逼,别急,听我娓娓道来:
为了避免每次在读写数据时访问磁盘增加 IO 开销,Innodb 存储引擎通过把相应的数据页和索引页加载到内存的缓冲池(buffer pool)中来提高读写速度。然后按照最近最少使用原则来保留缓冲池中的缓存数据。
那么当要读入的数据页不在内存中时,就需要到缓冲池中申请一个数据页,但缓冲池中数据页是一定的,当数据页达到上限时此时就需要把最久不使用的数据页从内存中淘汰掉。但如果淘汰的是脏页呢,那么就需要把脏页刷到磁盘里才能进行复用。
推荐阅读:https://zhuanlan.zhihu.com/p/59818056
7.3 分库分表
垂直分表和水平分表
垂直分表,就是将不常用的字端分到一个表中
垂直分库:按照业务将表进行分类,分布到不同的数据库上面,每个库可以放在不同的服务器上,它的核心理念是专库专用。
水平分表:是在同一个数据库内,把同一个表的数据按一定规则拆到多个表中 ,求模等就是
水平分库:是把同一个表的数据按一定规则拆到不同的数据库中,每个库可以放在不同的服务器上。
