iis服务器助手广告
返回顶部
首页 > 资讯 > 数据库 >慢SQL治理方法论
  • 759
分享到

慢SQL治理方法论

慢SQL治理方法论 2019-11-12 11:11:43 759人浏览 绘本
摘要

本文介绍了笔者实际工作中慢sql治理的方法论,1、发现:如何发现慢SQL。2、定位:如何定位到慢SQL写在哪。3、分析:遇到慢SQL时的分析思路。4、解决:慢SQL的解决思路。 @目录一、背景

慢SQL治理方法论

本文介绍了笔者实际工作中慢sql治理的方法论,1、发现:如何发现慢SQL。2、定位:如何定位到慢SQL写在哪。3、分析:遇到慢SQL时的分析思路。4、解决:慢SQL的解决思路。

@

目录
  • 一、背景
  • 二、发现
  • 三、定位
  • 四、分析
    • 4.1 索引层面分析
    • 4.2 业务层面分析
  • 五、解决
    • 5.1 SQL优化
      • 5.1.1索引优化
      • 5.1.2 子查询优化
      • 5.1.3 分页优化
      • 5.1.4 Using filesort文件排序优化
        • 解决
    • 5.2 业务改造
      • 5.2.1 总量显示优化
      • 5.2.1 关联表优化
    • 5.3 减少数据
  • 总结

一、背景

  从业务的角度来看:慢SQL会导致产品用户体验差,会减低用户对产品的好感度。
  从数据库的角度来看:慢SQL会影响数据库的性能,每个SQL执行都需要消耗一定的I/O资源。假设总资源是100,有一条慢SQL占用了30的资源共计1分钟。那么在这1分钟时间内,其他SQL能够分配的资源总量就是70,如此循环,当资源分配完的时候,所有新的SQL执行将会排队等待。

二、发现

  在治理慢SQL前我们需要知道哪些SQL是慢SQL,即明确治理的对象。Mysql本身提供了慢查询日志,当SQL耗时超过指定阈值的时候,会将SQL记录到慢查询日志文件中,用户能够从慢查询日志文件中提取出慢SQL。
  mysql是可以动态开启慢查询日志,即线上的服务器没有开启慢日志,重启后会失效。为防止线上业务受影响,可以先这样修改,同时将my.cnf配置文件补上配置项即可。

  • 查看配置

    • slow_query_log 是否启用慢查询日志
    • long_query_time 慢查询阈值
    • slow_query_log_file 慢查询日志文件slow.log位置
    show VARIABLES like "%query%";
    
  • 开启慢查询日志

  MySQL数据库默认不启动慢查询日志,需要手动设置,如果不是调优需要的话,一般不建议启动该参数,因为开启慢查询日志会或多或少带来一定的性能影响

# 开启慢查询日志
set global slow_query_log=ON;

# 慢查询阈值
set global long_query_time=1;

# 慢查询日志文件
set global slow_query_log_file=/tmp/mysql_slow.log

三、定位

  我们通过慢查询日志提取出慢SQL,将这些慢SQL按不同的应用进行区分并整理一份文档,再定位到对应应用的代码,在文档中记录慢SQL应用在什么业务中,运行在什么场景中(定时任务、在线实时查询等)。
image.png

四、分析

  接下来是根据整理的文档,对这些慢SQL做一些分析,找出慢SQL产生的原因。

4.1 索引层面分析

  使用explain命令输出SQL的执行计划,透过执行计划我们可以了解慢SQL的执行细节。

Mysql中的执行计划各列说明。

  • id: 按照sql语法解析后分层后的编号
  • type:执行计划中指定表使用的访问路径方式。

  这是个非常重要的字段,也是我们判断一个SQL执行效率的主要依据(以下只列举常见的几种)。
  依次从最优到最差分别为:system > const > eq_ref > ref > range > index > ALL

   - system:从系统表读一行。这是const联接类型的一个特例。
   - const:表最多有一个匹配行,它将在查询开始时被读取。const用于常数值比较PRIMARY KEY或UNIQUE索引的所有部分

image.png

  - eq_ref:它用在一个索引的所有部分被联接使用并且索引是UNIQUE或PRIMARY KEY。

image.png

   - ref:相比 eq_ref,不使用唯一索引,而是使用普通索引或者唯一性索引的部分前缀,索引要和某个值相比较,可能会找到多个符合条件的行。
- ref是我们日常开发中较为常见的情况,也是原则上期望要达到的级别,查询命中到索引。

image.png

  - range:索引范围扫描

image.png

   - index:只扫描索引树,不需要回表查询。在这种情况下,explain 的 Extra 列的结果是 Using index

image.png

   - all:全表扫描。

  • possible_keys:查找表中的行时可选择的索引。
  • key:显示MySQL实际决定使用的索引。
  • key_len:显示MySQL使用索引键的长度,就是此次查询所选择的索引长度有多少字节。
  • ref:ref字段标识哪些字段或者常量被用来和key配合从表中查询记录出来,如果为NULL表示没有
  • rows:该列表明MySQL估计要读取并检查的行数,需要注意的是,这个不是结果集里的行数
  • filtered:它指返回结果的行数(MySQL层where过滤生效的数据量)占需要扫描到的行数(rows列的值)的百分比,一般来说越高越好,越低证明查询代价越高。
  • Extra:该列包含MySQL解决查询的详细信息(以下只列举常见的几种)。
    • Using filesort:说明mysql会对数据使用一个外部的索引排序,而不是按照表内的索引顺序进行读取。
    • Using index:这个值重点强调了只需要使用索引就可以满足查询表的要求,不需要直接访问表数据了,一般表示使用了覆盖索引
    • Using temporary:这个值表示使用了内部临时表(基于内存的表)。这种情况通常发生在查询时包含了group by和order by子句,或者来自不同表的列使用了distinct。
    • Using where:where条件查询,通常using where表示优化器需要通过索引回表查询数据

4.2 业务层面分析

根据具体的业务场景进行考虑

  • 查询条件是否都是必须的
  • 查询时间范围可否缩短
  • 表里面存在的一些大字段,根据实际情况缩短字段长度
    • 如果不是每次都必须获取的话,可以考虑从当前表拆出去,主表都是小字段,子表维护大字段,这样效率会更高

五、解决

5.1 SQL优化

5.1.1索引优化

  1. 左前缀原则:索引了多个列时,查询时必须从最左列开始,不能跳过,否则索引失效
  2. 在使用不等于符号时(!=,<>)会索引失效
  3. 使用is not null会索引失效,但is null 不会
  4. like模糊查询中以通配符开头会索引失效
  5. 使用or时,左右两边的字段都需要加上索引,否则索引失效
  6. 在索引列上使用函数会索引失效
  7. 避免隐式类型转换-字符串类型字段不加单引号索引失效
  8. 有时候MySQL优化器选择的索引不一定是最优的,可以通过FORCE INDEX(idx_order_id)强制要求走某个索引,当然,必须保证这个索引以后不能被删除,不然就是个BUG

5.1.2 子查询优化

select something from user_table 
where id in (select user_id from order_table where xxx=yyyy);

  MySQL从5.7开始优化器对子查询进行了优化,会自动转换为join再执行,而对于5.7以下版本的MySQL 我们建议把子查询改成join的方式:

 select a.something
 from user_table a, order_table b
 where a.id=b.user_id
 and b.xxx=yyyy;

5.1.3 分页优化

  Limit中分页查询会随着pageNo增大而变缓慢,通过子查询+表连接解决
select * from mytbl order by id limit 100000,10 改进后的SQL语句如下:

select * from mytbl 
where id >= ( select id from mytbl order by id limit 100000,1 ) 
limit 10
# 或者
select * from mytbl 
inner join (select id from mytbl order by id limit 100000,10) as tmp 
on tmp.id=ori.id;

5.1.4 Using filesort文件排序优化

  orders建立了idx_ppo_created_at索引,使用EXPLAIN进行分析

EXPLAIN
SELECT id,
       temp_id,
       pos_id,
       `type`,
       member_id,
       temp_status,
       money_amount,
       trans_amount,
       return_trans_amount,
       coupon_id,
       cash_points,
       is_cancel,
       is_auto_cancel,
       is_compensate,
       is_multi_equity,
       company_id,
       store_id,
       store_type,
       source_orders,
       return_order_id,
       created_at,
       updated_at
FROM orders
WHERE 1 = 1
  AND `created_at` >= "2021-08-27 00:00:00"
  AND `created_at` <= "2021-08-27 23:59:59"
  AND `type` = 0
  AND `is_cancel` = 0
  AND `temp_status` = 0
ORDER BY id DESC
LIMIT 0,100

image.png
  我们可以看到Extra列出现了Using filesort,说明MySQL会对数据使用一个外部的索引排序, 而不是按照表内索引顺序进行读取。

解决

  因为索引的叶子节点数据是根据 created_at 有序的,我们可以利用这一点来避免排序。
  我们将 ORDER BY id DESC 换成 ORDER BY created_at DESC,查看执行计划,Using filesort 已消失:
image.png

5.2 业务改造

  如果SQL本身的性能已经到达极限了,但是耗时仍然很长。这时候,我们可以业务角度着手,看看在业务上能不能做一些变通、妥协。

5.2.1 总量显示优化

image.png
  如上图所示,我们在做分页时,页底都会展示符合条件的记录总数,以及分页页数。数据量少的时候,不会带来性能问题,但如果数据量较大,这个计算总量的count() 本身就不会太快,再加上每次打开页面都要计算一次的话,那这样会就带性能问题了,同时也会拖慢页面打开速度。
  如果业务上允许,当数据量少时,精确显示,当数据量过大后,用户对真实数据不敏感时,那我们就可以通过 1000+ 等模糊的方式进行初步显示,减少不必要的扫描,同时也可以让用户首次打开时达到加速效果。
原SQL:select count(
) from table where xxx=yyy;
调整后:select count(*) from (select id from table where xxx=yyy limit 1000);

5.2.1 关联表优化

  由于业务很复杂,某条SQL关联了很多表,导致表关联时的匹配耗时很长。这时候可以看看能不能将多关联SQL改成较少表的关联,使用代码方式进行关联,但是会增加请求次数。

5.3 减少数据

  如果单表行数超过500万行或者单表容量超过2GB,SQL再怎么优化还是会慢,这个时候就要做数据拆分,这属于架构层面的变动,影响的面很大,除了慢SQL本身之外,其他的相关SQL也可能会被“波及”到。这种慢SQL治理的手段,能够一定程度上解决慢SQL问题。减少作用数据的方式有:

  • 垂直拆分
  • 水平拆分
  • 综合拆分(垂直+水平)

总结

本文介绍了实际工作中慢SQL治理的方法论
1、发现:如何发现慢SQL。
2、定位:如何定位到慢SQL写在哪。
3、分析:遇到慢SQL时的分析思路。
4、解决:慢SQL的解决思路。

  SQL优化本身是一个比较复杂的问题,上面所列举的,只是部份优化的案例,但所有优化的思路都是尽可能的减少SQL在执行中过程中扫描数据块的次数,只要遵从这一核心思想,SQL优化并不是什么太难的事情。
  以上就是今天要讲的内容,本文是笔者实际治理过程中的一些总结和心得,如有不正之处,还请指正。

原文地址:https://www.cnblogs.com/zhihong1/arcHive/2022/03/17/16018136.html

您可能感兴趣的文档:

--结束END--

本文标题: 慢SQL治理方法论

本文链接: https://www.lsjlt.com/news/9202.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • SQL-方法论
    写SQL时可以考虑的手段: 行转列 先分为多个临时表,然后JOIN到一起 select uid, t1.name YuWen, t2.name ShuXuefrom (select uid, ...
    99+
    2023-09-21
    sql 数据库 hive
  • 清理MySQL 慢sql日志的方法 & flush log/table 注意事项
    方法一: 进入mysql,执行set global slow_query_log=0; 将慢sql日志删除或改名备份: rm -rf slow.log 或 mv slow.log slow.log_20230403 进入mysql,执行se...
    99+
    2023-09-21
    mysql sql 数据库
  • SQL慢查询优化的方法是什么
    本篇内容主要讲解“SQL慢查询优化的方法是什么”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“SQL慢查询优化的方法是什么”吧!1.背景页面无法正确获取数据,经排查原来是接口调用超时,而最后发现是...
    99+
    2023-06-26
  • sql慢查询解决方案
    一、慢查询产生原因 大体有以下三种可能: 1、索引没有设计好; 2、SQL 语句没写好; 3、MySQL 选错了索引。 二、慢查询解决方案 1、针对索引没有设计好的解决方案:给表重新加索引重新加索引 2、针对SQL 语...
    99+
    2023-09-01
    sql 数据库 mysql Powered by 金山文档
  • Nacos Discovery服务治理解决方案
    目录前言服务治理什么是服务治理?常见的注册中心ZookeeperEurekaConsulNacosNacos 入门搭建nacos环境将商品微服务注册到nacos将订单微服务注册到na...
    99+
    2022-11-13
    Nacos Discovery服务 Nacos Discovery Nacos Discovery服务治理
  • CodeReview方法论与实践总结梳理
    目录引言为什么要CR他山之石2.1 某大厂A2.1.1 代码评审准则2.1.2 代码评审原则2.1.3 代码审核者应该看什么2.2 某大厂B2.3 某大厂C我们怎么做 CR3.1 作...
    99+
    2023-02-07
    Code Review 方法论 Code Review
  • 一个20秒SQL慢查询优化处理方案
    目录1.背景2.复杂SQL语句的构成3.关联查询4.子查询5.耗时在哪?6.问题定位7.初步断定9.再进一步验证10.解决方案11.另外一个需要注意的点1.背景 页面无法正确获取数据...
    99+
    2024-04-02
  • .Net Core服务治理Consul健康检查方法是什么
    这篇文章主要讲解了“.Net Core服务治理Consul健康检查方法是什么”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“.Net Core服务治理Consul健康检查方...
    99+
    2023-06-26
  • MySQL慢SQL采集方案分析
    本篇内容主要讲解“MySQL慢SQL采集方案分析”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“MySQL慢SQL采集方案分析”吧!作为一名MySQL DBA,首...
    99+
    2024-04-02
  • SQL Server性能调优方法论及常用工具有哪些
    本篇文章给大家分享的是有关SQL Server性能调优方法论及常用工具有哪些,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。说起“调优”,可能会...
    99+
    2024-04-02
  • ChatGPT写论文的方法
    ChatGPT写论文的方法:1、创建一个帐户访问chatgpt;2、转到左下角的chatGPT部分或标题中的TRY部分;3、确定要写...
    99+
    2023-02-08
    ChatGPT
  • CSS方法论有哪些
    这篇文章主要介绍“CSS方法论有哪些”,在日常操作中,相信很多人在CSS方法论有哪些问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”CSS方法论有哪些”的疑惑有所帮助!接下来,...
    99+
    2024-04-02
  • MySQL定位并优化慢查询sql的方法是什么
    本篇内容介绍了“MySQL定位并优化慢查询sql的方法是什么”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!1.如何定位并优化慢查询sql  ...
    99+
    2023-06-22
  • SQL Server代理:理解SQL代理错误日志处理方法
    SQL Server代理是所有实时数据库的核心。代理有很多不明显的用法,因此系统的知识,对于开发人员还是DBA都是有用的。这系列文章会通俗介绍它的很多用法。 如我们在这个系列的前几篇...
    99+
    2024-04-02
  • 分布式理论协议与算法 第三弹 BASE理论
    大部分人解释这 CAP 定律时,常常简单的表述为:“一致性、可用性、分区容错性三者你只能同时达到其中两个,不可能同时达到”。实际上这是一个非常具有误导性质的说法,而且在 CAP 理论诞生 12 年之后,CAP 之父也在 2012 年重写...
    99+
    2023-08-18
    分布式 java 大数据
  • sql server卡慢问题定位与排查的方法是什么
    这篇“sql server卡慢问题定位与排查的方法是什么”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下...
    99+
    2023-03-08
    sqlserver
  • Java实现格式化打印慢SQL日志的方法详解
    目录前言一、主要作用:二、代码实现:2.1 单条记录类(LogStatement ):2.2 逻辑处理类(MySQLSlowLogParser):2.2.1 成员变量2.2.2 ma...
    99+
    2022-11-13
    java 格式化打印 java 慢sql日志 java格式化输入输出
  • Rainbond网络治理插件ServiceMesh官方文档说明
    目录ServiceMesh网络治理插件插件实践​综合网络治理插件​入站方向​出站方向​出站网络治理插件​ServiceMesh网络治理插件 5.1.5版本后,Rainbond默认提供...
    99+
    2024-04-02
  • SQL代理错误日志处理方法
    这篇文章主要讲解了“SQL代理错误日志处理方法”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“SQL代理错误日志处理方法”吧!SQL Server代理是所有实时数据库的核心。代理有很多不明显的...
    99+
    2023-06-20
  • 讨论golang channel的实现方法
    Golang是一门相对年轻的编程语言,但它已经受到越来越多的开发者的关注。这是它可以轻松地与其他语言进行交互和使用,并且它有一个强大且简单的并发模型,其中包括channel。本文将讨论golang channel的实现方法及其用途。什么是g...
    99+
    2023-05-14
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作