文章初衷
我们发现在体系上线初期,SQL运行都是正常的,但是到了业务稳定运行以后,在数据量达到一定水平,我们会发现越来越多的慢SQL出现,严重影响用户体验。
目录
文章初衷
慢SQL的定义
⚠️留意:后两个案例更出色!
【实战】
慢SQL调优---三板斧第一招【由内到外】
慢SQL调优---三板斧第二招【小表驱动大表】
原始SQL
调解次序
慢SQL调优---三板斧第三招【条件前置】
原始SQL
优化后的语句
想知道本篇文章是否对您有帮助,让我有更新下一篇的动力。如果有帮助可以批评“有”,非常感谢各位观众老爷们!
慢SQL的定义
慢SQL,即执行时间较长的SQL查询语句,通常指的是在数据库管理体系中执行时间超过预设阈值的SQL语句。这个阈值可以由数据库管理员根据体系性能和业务需求来设定,常见的阈值可能是2秒、5秒或更长。当一个SQL查询的执行时间超过了这个阈值,它就会被标志为“慢查询”。
慢SQL的存在可能表明数据库性能存在瓶颈,如索引设计不合理、查询逻辑复杂、数据量过大、硬件资源不足等题目。它们会占用更多的CPU、I/O资源,影响数据库的响应速度,低落团体体系性能,乃至导致体系响应耽误或崩溃。
为了优化慢SQL,数据库管理员和开发人员通常必要对其举行详细的分析,包括检察执行筹划、查抄索引使用情况、优化查询语句布局、调解数据库参数等,以提高查询效率和体系性能。别的,定期检察慢查询日志也是发现和解决慢SQL题目标有效本领。
请耐心看完,包管你的优化思路会更加清晰。
⚠️留意:后两个案例更出色!
最后附上《30个业务场景的SQL优化》、《老司机总结的12条 SQL 优化方案》
【实战】
慢SQL调优---三板斧第一招【由内到外】
话不多说,我们进入实战,以下是我们生产环境的一段查询SQL,它运行耗时在157.84秒,那么各人可以想一想,如果是你,看到这一段SQL会怎么入手呢?
原始SQL
- SELECT CL.SCRQSTR,
- TEAM.TEAMCODE AS BMID,
- O.BATCHNO,
- O.STYLE_NO,
- O.PO_ID,
- SUM(CL.QTY)AS QTY,
- MX.MXBRS,
- MXBGS.WORK_SEC AS MXGS,
- O.ORDERTYPE,
- O.FACTORY_NAME,
- O.DIC_ORDER_NO,
- O.DIC_ROW_NO,
- O.ORDER_NO FROM
- (SELECT DISTINCT SCRQSTR,
- QTY,
- LSXNO,
- ORDER_NO,
- PROCESSID,
- BID
- FROM T_DG_CLXX
- WHERE CREATE_DATE>='2024-06-21 13:20:00'
- AND CREATE_DATE<'2024-06-21 13:30:00')CL
- INNER JOIN T_TEAM_SUSPEND T1
- ON T1.LSXNO=CL.LSXNO
- INNER JOIN T_BASIC_TEAM TEAM
- ON TEAM.ID=T1.ID
- INNER JOIN T_PRODUCTION_ORDER O
- ON O.ORDER_NO=CL.ORDER_NO
- INNER JOIN PROCESS_PATH PATH
- ON PATH.CID=CL.PROCESSID
- AND PATH.PO_ID=O.PO_ID
- AND PATH.WORKID=3
- INNER JOIN
- (SELECT COUNT(*)AS MXBRS,
- T.ORDER_NO FROM
- (SELECT DISTINCT USERID,
- ORDER_NO
- FROM T_DG_CLXX
- WHERE CREATE_DATE>='2024-06-21 13:20:00'
- AND CREATE_DATE<'2024-06-21 13:30:00'
- AND LSXNO NOT IN(1,16))T
- GROUP BY T.ORDER_NO)MX
- ON MX.ORDER_NO=CL.ORDER_NO
- INNER JOIN
- (SELECT SUM(CASE
- WHEN T.WORK_SEC>600 THEN
- 600
- WHEN T.WORK_SEC<10 THEN
- 150
- ELSE T.WORK_SEC END)AS WORK_SEC,ORDER_NO FROM
- (SELECT DISTINCT SCRQ,
- WORK_SEC,
- MODULE_ID,
- SEAT_CODE,
- PIECES,
- USERID,
- LSXNO,
- ORDER_NO
- FROM T_DG_CLXX
- WHERE CREATE_DATE>='2024-06-21 13:20:00'
- AND CREATE_DATE<'2024-06-21 13:30:00'
- AND LSXNO NOT IN(1,16))T
- GROUP BY T.ORDER_NO)MXBGS
- ON MXBGS.ORDER_NO=CL.ORDER_NO
- GROUP BY CL.SCRQSTR,TEAM.TEAMCODE,O.BATCHNO,O.STYLE_NO,O.PO_ID,MX.MXBRS,MXBGS.WORK_SEC,O.ORDERTYPE,O.FACTORY_NAME,O.DIC_ORDER_NO,O.DIC_ROW_NO,O.ORDER_NO
复制代码
你是不是也以为很棘手?感觉有业务逻辑,关联了很多表,也有很多子查询。
首先我们可以先对SQL中的子查询举行执行,看是否存在慢SQL,从内到外去剖析。比如以上这段SQL可以单独执行子查询,检察所需耗时。
首先第一个子查询,但是我们不知道这个表有多少数据量,以是我们必要截取前面10条即可,mysql添加条件limit 10,如果是Oracle就是where rownum < 11,执行发现,SQL超过30秒都没有出结果。
- SELECT DISTINCT SCRQSTR,
- QTY,
- LSXNO,
- ORDER_NO,
- PROCESSID,
- BID
- FROM T_DG_CLXX
- WHERE CREATE_DATE>='2024-06-21 13:20:00'
- AND CREATE_DATE<'2024-06-21 13:30:00' LIMIT 10;
复制代码 因此可以判断这个SQL语句异常,可以通过EXPLAIN 来检察是否走索引了,再看一下T_DG_CLXX表有多少数据量。
通过EXPLAIN发现SQL没有走索引,说明CREATE_DATE字段没有建立索引。另外查询发现此表有3700万条数据量,也发现此表会每年举行数据归档,必须保留1年数据。
那么小同伴知道接下来要做什么了吗?
--------------------------------------------------------------------------------------
没错,建立索引!
建立索引以后,查询为0.1秒左右。
然后将原先业务SQL重新执行,查询时间为0.135秒,效率提升1169倍
这个案例很简朴,CREATE_DATE字段由于是后面业务必要,属于新增的字段。增长字段忘记增长索引,后面出现题目过一次,但是研发又忘记添加索引了,后面我们运维团队通过慢SQL预警发现了这条SQL异常。
慢SQL调优---三板斧第二招【小表驱动大表】
前面谁人案例是不是很简朴,下面这个看到调优结果也会以为很简朴,但是很经典。
给我一个支点,我能翘起整个 |