Sql优化经验

102 阅读2分钟

sql优化经验

场景1:慢sql报警

场景1:按更新时间查询公司数据的一个业务,然后下游有一个服务,定时任务每天中午十二点调这个接口刷全量的数据,然后这个服务每天12点半就开始报警,开始爆大量的慢sql,这个慢sql多到一定程度之后会影响到数据库的性能。

解决:本质上是一个深分页的问题,越往后面查询越慢,mysql还会从第一页一直扫到这一页。这个问题没办法去建立索引或者改索引去解决。我们本身更新时间上也会有索引。我是这样解决的,本身下游服务的目的去刷全量的数据,我改了一下,让它去传一个id过来,id是公司的主键,而且这个主键是自增的,你第一次传的时候就传0,然后第二次传的时候就传我返回给你的最大的id。然后我每次给你查询返回500条数据。只不过我有一个逻辑判断,我只会返回大于你传过来id的500条数据。我把分页查询转换为范围查询,解决了慢sql的问题

场景2:大数据量查询

场景2:还有特别大的数据量的时候,查询特别慢,而且当时这个特别老的服务,我们就想以最小的改动获取最大的收益。

解决:我们知道mysql的10亿条数据,一定是一个四层的B+树,相比于三层B+树只多了一次随机IO读取。我做个实验多一次随机IO其实不会对查询时间造成多大影响,所以这个问题主要不是这个造成的,后面我想当mysql不是有一层缓冲区嘛,缓存着上一次读取的页在内存中,第一次查询的数据会放到bufferPool中,第二次查询如果缓存命中就直接取出,所以当时是把缓冲区几百个兆的改为几个g的就解决了

优化思路

插入优化:批量插入,手动提交事务,load指令将文件一次性插入到mysql

update优化: update后面where的条件字段+索引,否则会从行锁升级为表锁

主键优化: 顺序插入,否则页分裂,减少主键长度,因为二级索引存放主键

order by和group by优化: 将要排序的字段+索引

Limit深分页优化: 覆盖索引+子查询优化

count用法: count(*)底层优化了,服务器直接累加

联表优化: 小表驱动大表