慢查询优化方案

如果你的项目中出现了一些查询超时情况,很可能是项目中有了一些慢查询的情况产生,下面就慢查询的排查和解决方案进行一番分析。

sql排查方式

首先,如何排查sql是否走了索引,通过explain关键字找出sql的执行计划,通过在对执行计划的分析,找出某表关联部分是否走了索引。
具体语法:

explain select * from table_name;

具体执行计划的指标含义,详见:Sql执行计划的一些指标含义

让不走索引的sql走索引

mysql有个特别神奇的东西叫做索引,一个sql走或不走索引,查询效率差别极大,因此大部分的查询效率问题都是不走索引造成的,也就意味着,只要找到不走索引的原因,就能解决大部分查询效率的问题。因此专门开了一个文章罗列不走索引的情况,欢迎大家补充或指正。
不走索引的情况及一些规避方案

联合索引,避免回表

众所周知,联合索引的叶子节点存储了索引字段的值,因此,合理的设计联合索引,可以避免回表操作。比如:我的表中有四十个字段,但是查询频率比较高的只有a,b,c三个字段,这时候,如果我想进一步提升效率,我可以将abc三个字段设计一个联合索引,查询的速度就会有进一步提升。

特殊优化,深度分页

深度分页: 指的是在分页查询的时候,页数标记的特别高(如查询第10000页的数据),这样,如果正常查询的sql会出现 select * from table_name limit 10000,10 的sql出现,会造成极大的性能问题。因此深度分页问题需要有一定的优化。

方案一:从业务方面搞定,因为很多业务根本用不到那么多分页,那么就可以限制最大分页的页数,比如百度的最大显示页码就只有76页。
在这里插入图片描述

业务方面如果搞不定,只能通过技术手段搞定,那么我们就分析一下问题出在哪?

我们能够想到,性能瓶颈出在了limit页码过大的问题上,我们知道,索引的结构(B+树)有一个特性,就是叶子节点之间依靠双向链表连接,这个特性主要是针对范围查询做的优化,因此在进行分页查询的时候,我们会直接通过链表进行查询,问题就出在了这里,由于页码过大,而且查询字段过多,每次查询时候需要回表,所以链表在遍历的时候时间过长,造成了性能瓶颈。因此引申出了下面两个优化方案。

方案二:分页查询时将id作为查询条件传过来,然后往后查十条,这样可以先通过索引锁定到第一条数据,然后通过链表往后遍历十条数据,从而达到优化的效果。
如果你的已有的方案不是那么方便改,可以考虑下边的方案。

方案三:在sql中先分页查询到id(不需回表查询速度较快),然后在进行表关联进行分页查询,具体sql如下(类似):

select table.* from table_name as table inner join ( select id from table limit 3000000,10 ) as tmp on tmp.id=table.id;

突破瓶颈,分库分表

分库

每个数据库是有一个最大连接数的,超过这个连接数会查询超时,所以,在你的项目的并发量超过一定量级之后,你就需要考虑分库了,至于具体分多少个库,看实际QPS量有多少,一个库默认的连接数是100,按照具体QPS推算需要分出多少个库。

分表

分表又分为水平分表垂直分表
水平分表: 是将一张表的字段拆分到两张表上,从而达到单表数据存储量降低的目的。一般应用的场景都是按照业务含义拆分,可以拆分成多张一对一的表,各个表通过主键关联,比如将sku表拆分成sku基础信息表,sku扩展表,sku状态表,等等。
垂直分表: 是单表数据过多后,会导致数据查询时候读盘次数增加,从而查询效率降低,这时候就考虑将数据分到多张表上,通常做法是确定一个拆分键,将拆分键进行一定的算法(比如:hash运算后按照分表数取模),最终落到某张表中。
基本上单表量级超过两千万就可以考虑分表了,分多少表按照 最大量级除以500-1000万 左右数据计算。至于为什么最大阈值是两千万,可以看下 mysql B+树 索引机制InnoDB一棵B+树可以存放多少行数据? 深入了解一下。

削峰操作,临时缓存

有一种慢查询的情况是出在了一种峰值查询的时候,就是有时候会出现某个时间段有些业务几种出,但是定时任务过于集中,导致某一个短暂的时间段QPS暴增,从而数据库扛不住压力,出现了慢查询甚至于数据库崩溃,由于是峰值的问题,扩容机器又很浪费,不扩容又扛不住压力,为了避免这类问题,可以考虑引入缓存机制进行削峰操作,通过缓存机制短暂的保存数据库信息,让峰值的请求都压在缓存上,从而间接的避免了慢查询的情况

当然,无论是使用缓存中间件Redis,或者内存中间件MemoryCache都可以解决这类问题。

以慢打快,异步处理

同样是慢查询出现定时任务批量处理数据的情况,但是定时任务过于集中,导致某一个短暂的时间段QPS暴增,这时候更好的方案是通过mq异步处理数据,通过控制mq的消费密度来减轻qps,从而达到减轻数据库的压力,以时间换空间,以慢打快,效果奇好。

更换思路,曲线救国

如果是在查询效率提升不上去,就考虑更换查询中间件吧,使用大数据的处理方式,比如,落ElasticSearch查询。

  • 25
    点赞
  • 43
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

摆烂的小趴菜

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值