解析:
优化 shema、sql 语句+索引;
加缓存,memcached, redis;
主从复制,读写分离;
垂直拆分,根据你模块的耦合度,将一个大的系统分为多个小的系统,也就是分布式系统;
水平切分,针对数据量大的表,这一步最麻烦,最能考验技术水平,要选择一个合理的
sharding key, 为了有好的查询效率,表结构也要改动,做一定的冗余,应用也要改,sql 中
尽量带 sharding key,将数据定位到限定的表上去查,而不是扫描全部的表;
关心过业务系统里面的 sql 耗时吗?统计过慢查询吗?对慢查询都怎么优化过?
解析:
在业务系统中,除了使用主键进行的查询,其他的我都会在测试库上测试其耗时,慢查
询的统计主要由运维在做,会定期将业务中的慢查询
反馈给我们。
慢查询的优化首先要搞明白慢的原因是什么? 是查询条件没有命中索引?是 load了不
需要的数据列?还是数据量太大?
所以优化也是针对这三个方向来的:
- 首先分析语句,看看是否 load 了额外的数据,可能是查询了多余的行并且抛弃掉
了,可能是加载了许多结果中并不需要的列,对语句进行分析以及重写。
- 分析语句的执行计划,然后获得其使用索引的情况,之后修改语句或者修改索引,
使得语句可以尽可能的命中索引。
- 如果对语句的优化已经无法进行,可以考虑表中的数据量是否太大,如果是的话可
以进行横向或者纵向的分表。
解析:
- 访问数据太多导致查询性能下降
- 确定应用程序是否在检索大量超过需要的数据,可能是太多行或列
- 确认 MySQL 服务器是否在分析大量不必要的数据行
- 避免犯如下 SQL 语句错误
- 查询不需要的数据。解决办法:使用 limit 解决
- 多表关联返回全部列。解决办法:指定列名
- 总是返回全部列。解决办法:避免使用 SELECT *
- 重复查询相同的数据。解决办法:可以缓存数据,下次直接读取缓存
- 是否在扫描额外的记录。解决办法:
- 使用 explain 进行分析,如果发现查询需要扫描大量的数据,但只返回少数的行,可以
通过如下技巧去优化:
- 使用索引覆盖扫描,把所有的列都放到索引中,这样存储引擎不需要回表获取对应行就
可以返回结果。
- 改变数据库和表的结构,修改数据表范式
- 重写 SQL 语句,让优化器可以以更优的方式执行查询。
解析:
- 一个复杂查询还是多个简单查询
- MySQL 内部每秒能扫描内存中上百万行数据,相比之下,响应数据给客户端就要慢得
多
- 使用尽可能小的查询是好的,但是有时将一个大的查询分解为多个小的查询是很有必要
的。
- 切分查询
- 将一个大的查询分为多个小的相同的查询
- 一次性删除 1000 万的数据要比一次删除 1 万,暂停一会的方案更加损耗服务器开销。
- 分解关联查询,让缓存的效率更高。
- 执行单个查询可以减少锁的竞争。
- 在应用层做关联更容易对数据库进行拆分。
- 查询效率会有大幅提升。
- 较少冗余记录的查询。
解析:
- count(*)会忽略所有的列,直接统计所有列数,不要使用 count(列名)
- MyISAM 中,没有任何 where 条件的 count(*)非常快。
- 当有 where 条件时,MyISAM 的 count 统计不一定比其它引擎快。
- 可以使用 explain查询近似值,用近似值替代 count(*)
- 增加汇总表
- 使用缓存