一条SQL引起的系统不可用

一.前言

最近在运维系统,系统对客端突然报了403错误,从后台看发现了大量的慢SQL,导致查询超时,仔细分析我从来没见过那么厚颜无耻的SQL,一条SQL语句关联了一个大表(6000数据)查询了10次。我也很少见过一个SQL语句写了500多行。将一个很大的任务放在一个SQL里计算。以前能跑得起来是因为数据量少,现在表的数据量增加到6000万。性能急剧下降。

二、慢SQL分析(没见过如此厚颜无耻的SQL)

selectcount(1) as cnt,user_tag_user_life_period as label_value,'user_tag_user_life_period' as label_english
fromdata_tag.tag_user_attribute_all
whereone_id global in (selectone_idfromdata_dwd.big_table finalwhere((casewhen reg_time_taxfree is not null then 1else 0end) + (casewhen reg_time_hotel is not null then 1else 0end) + (casewhen reg_time_travel is not null then 1else 0end) + (casewhen reg_time_invest is not null then 1else 0end)) >= 2)
group byuser_tag_user_life_period
havinguser_tag_user_life_period is not nulland user_tag_user_life_period <> ''
order bycnt desc
limit1
union all
selectcount(1) as cnt,user_tag_level_name_taxfree as label_value,'user_tag_level_name_taxfree' as label_english
fromdata_tag.tag_user_attribute_all
whereone_id global in (selectone_idfromdata_dwd.big_table finalwhere((casewhen reg_time_taxfree is not null then 1else 0end) + (casewhen reg_time_hotel is not null then 1else 0end) + (casewhen reg_time_travel is not null then 1else 0end) + (casewhen reg_time_invest is not null then 1else 0end)) >= 2)
group byuser_tag_level_name_taxfree
havinguser_tag_level_name_taxfree is not nulland user_tag_level_name_taxfree <> ''
order bycnt desc
limit1
union all
selectcount(1) as cnt,user_tag_level_name_travel as label_value,'user_tag_level_name_travel' as label_english
fromdata_tag.tag_user_attribute_all
whereone_id global in (selectone_idfromdata_dwd.big_table finalwhere((casewhen reg_time_taxfree is not null then 1else 0end) + (casewhen reg_time_hotel is not null then 1else 0end) + (casewhen reg_time_travel is not null then 1else 0end) + (casewhen reg_time_invest is not null then 1else 0end)) >= 2)
group byuser_tag_level_name_travel
havinguser_tag_level_name_travel is not nulland user_tag_level_name_travel <> ''
order bycnt desc
limit1
union all
selectcount(1) as cnt,user_tag_level_name_hotel as label_value,'user_tag_level_name_hotel' as label_english
fromdata_tag.tag_user_attribute_all
whereone_id global in (selectone_idfromdata_dwd.big_table finalwhere((casewhen reg_time_taxfree is not null then 1else 0end) + (casewhen reg_time_hotel is not null then 1else 0end) + (casewhen reg_time_travel is not null then 1else 0end) + (casewhen reg_time_invest is not null then 1else 0end)) >= 2)
group byuser_tag_level_name_hotel
havinguser_tag_level_name_hotel is not nulland user_tag_level_name_hotel <> ''
order bycnt desc
limit1
union all
selectcount(1) as cnt,user_tag_taxfree_and_travel_sex as label_value,'user_tag_taxfree_and_travel_sex' as label_english
fromdata_tag.tag_user_attribute_all
whereone_id global in (selectone_idfromdata_dwd.big_table finalwhere((casewhen reg_time_taxfree is not null then 1else 0end) + (casewhen reg_time_hotel is not null then 1else 0end) + (casewhen reg_time_travel is not null then 1else 0end) + (casewhen reg_time_invest is not null then 1else 0end)) >= 2)
group byuser_tag_taxfree_and_travel_sex
havinguser_tag_taxfree_and_travel_sex is not nulland user_tag_taxfree_and_travel_sex <> ''
order bycnt desc
limit1
union all
selectcount(1) as cnt,user_tag_taxfree_and_travel_user as label_value,'user_tag_taxfree_and_travel_user' as label_english
fromdata_tag.tag_user_attribute_all
whereone_id global in (selectone_idfromdata_dwd.big_table finalwhere((casewhen reg_time_taxfree is not null then 1else 0end) + (casewhen reg_time_hotel is not null then 1else 0end) + (casewhen reg_time_travel is not null then 1else 0end) + (casewhen reg_time_invest is not null then 1else 0end)) >= 2)
group byuser_tag_taxfree_and_travel_user
havinguser_tag_taxfree_and_travel_user is not nulland user_tag_taxfree_and_travel_user <> ''
order bycnt desc
limit1
union all
selectcount(1) as cnt,user_tag_taxfree_and_hotel_sex as label_value,'user_tag_taxfree_and_hotel_sex' as label_english
fromdata_tag.tag_user_attribute_all
whereone_id global in (selectone_idfromdata_dwd.big_table finalwhere((casewhen reg_time_taxfree is not null then 1else 0end) + (casewhen reg_time_hotel is not null then 1else 0end) + (casewhen reg_time_travel is not null then 1else 0end) + (casewhen reg_time_invest is not null then 1else 0end)) >= 2)
group byuser_tag_taxfree_and_hotel_sex
havinguser_tag_taxfree_and_hotel_sex is not nulland user_tag_taxfree_and_hotel_sex <> ''
order bycnt desc
limit1
union all
selectcount(1) as cnt,user_tag_taxfree_and_hotel_user as label_value,'user_tag_taxfree_and_hotel_user' as label_english
fromdata_tag.tag_user_attribute_all
whereone_id global in (selectone_idfromdata_dwd.big_table finalwhere((casewhen reg_time_taxfree is not null then 1else 0end) + (casewhen reg_time_hotel is not null then 1else 0end) + (casewhen reg_time_travel is not null then 1else 0end) + (casewhen reg_time_invest is not null then 1else 0end)) >= 2)
group byuser_tag_taxfree_and_hotel_user
havinguser_tag_taxfree_and_hotel_user is not nulland user_tag_taxfree_and_hotel_user <> ''
order bycnt desc
limit1
union all
selectcount(1) as cnt,user_tag_last_year_amount as label_value,'user_tag_last_year_amount' as label_english
fromdata_tag.tag_user_attribute_all
whereone_id global in (selectone_idfromdata_dwd.big_table finalwhere((casewhen reg_time_taxfree is not null then 1else 0end) + (casewhen reg_time_hotel is not null then 1else 0end) + (casewhen reg_time_travel is not null then 1else 0end) + (casewhen reg_time_invest is not null then 1else 0end)) >= 2)
group byuser_tag_last_year_amount
havinguser_tag_last_year_amount is not nulland user_tag_last_year_amount <> ''
order bycnt desc
limit1
union all
selectcount(1) as cnt,user_tag_last_year_frequency as label_value,'user_tag_last_year_frequency' as label_english
fromdata_tag.tag_user_attribute_all
whereone_id global in (selectone_idfromdata_dwd.big_table finalwhere((casewhen reg_time_taxfree is not null then 1else 0end) + (casewhen reg_time_hotel is not null then 1else 0end) + (casewhen reg_time_travel is not null then 1else 0end) + (casewhen reg_time_invest is not null then 1else 0end)) >= 2)
group byuser_tag_last_year_frequency
havinguser_tag_last_year_frequency is not nulland user_tag_last_year_frequency <> ''
order bycnt desc
limit 1;

这个SQL引发系统403,

一个重要设计缺陷是查询频繁。

第二个是这个查询放在对客端的微服务中开启了线程,这种设计严重影响对客端的性能和流畅度,这种业务应放在后台管理系统计算,而不是对客端。

第三、就是这个业务没有进行分解,是个大业务SQL 。

第四、这是一个无耻不考虑后果的SQL。没有考虑到单表数据量的暴增。

三、如何解决慢SQL和避免慢SQL

解决慢SQL(慢查询)和避免慢SQL是数据库优化中的关键任务。以下是一些建议和方法,可以帮助你解决和避免慢SQL:

1. 优化查询语句

  • 使用索引:确保查询中使用的字段都已经建立了索引,这可以大大提高查询速度。
  • **避免SELECT ***:只选择需要的字段,而不是选择所有字段。
  • 使用连接(JOIN)代替子查询:当可能时,使用JOIN操作代替子查询。
  • 优化WHERE子句:避免在WHERE子句中使用函数或计算,这会导致索引失效。

2. 优化数据库设计

  • 正规化:通过正规化来减少数据冗余。
  • 反正规化:在某些情况下,为了查询性能,可以故意引入一些冗余。
  • 分区:将大表分区,可以提高查询性能。

3. 优化数据库配置

  • 调整缓存大小:根据工作负载调整数据库的缓存大小。
  • 调整I/O性能:确保数据库服务器有足够的I/O性能。
  • 监控和调整并发连接数:根据实际需要调整最大并发连接数。

4. 使用分析工具

  • 慢查询日志:启用数据库的慢查询日志功能,找出执行时间长的查询。
  • EXPLAIN计划:使用EXPLAIN语句查看查询的执行计划,找出性能瓶颈。

5. 硬件和存储优化

  • 使用更快的存储:例如,使用SSD替代HDD。
  • 增加内存:为数据库服务器增加更多的内存。
  • 优化I/O配置:确保I/O子系统(如RAID配置)是最优的。

6. 避免常见错误

  • 避免在循环中执行查询:这会导致大量的数据库连接和查询。
  • 避免使用LIKE操作符进行前缀模糊匹配:这会导致全表扫描。

7. 定期维护

  • 更新统计信息:定期更新数据库的统计信息,以便优化器做出更好的决策。
  • 重建索引:定期重建或优化索引,保持其性能。

8. 考虑使用缓存

  • 查询缓存:某些数据库支持查询缓存,可以考虑启用。
  • 外部缓存:如Redis或Memcached,用于缓存热点数据。

9. 考虑分布式解决方案

  • 读写分离:将读操作和写操作分离到不同的服务器上。
  • 分片:将数据分布到多个数据库服务器上。

10. 持续监控和学习

  • 监控数据库性能:使用监控工具持续监控数据库性能。
  • 持续学习:数据库技术和最佳实践在不断变化,保持学习是关键。

 四、常见SQL优化方法

常见的SQL优化方法包括以下几个方面:

  1. 选择特定字段:尽量避免使用SELECT *,而是选择你真正需要的具体字段。这样可以减少不必要的数据传输和处理,从而提高查询效率。

  2. 使用索引:确保查询中使用的字段都已经建立了索引。索引可以大大提高查询速度,因为数据库可以快速定位到数据而不需要全表扫描。

  3. 优化WHERE子句

    • 避免在WHERE子句中使用函数或计算,因为这会导致索引失效。
    • 尽量避免使用OR来连接条件,因为当OR两边的字段不是索引字段时,查询可能不走索引。
    • 尽量避免在索引列上使用MySQL的内置函数。
  4. 优化JOIN操作:优先使用INNER JOIN,如果是LEFT JOIN,确保左边表的结果集尽量小。

  5. 使用LIMIT:当只需要一条或少数几条记录时,使用LIMIT来限制返回的结果集大小。

  6. 优化LIKE查询:尽量避免使用前缀模糊查询(如LIKE '%li%'),因为它会导致全表扫描。如果可能,尽量使用后缀模糊查询(如LIKE 'li%')。

  7. 避免使用子查询:当可能时,使用JOIN操作代替子查询。

  8. 优化排序操作:如果排序字段没有用到索引,尽量减少排序操作。

  9. 考虑表的设计:正规化和反正规化可以影响查询性能。确保你的表设计是合理的,并且考虑了查询性能。

  10. 使用分析工具:利用数据库的慢查询日志功能和EXPLAIN计划来找出性能瓶颈。

  11. 硬件和存储优化:确保数据库服务器有足够的硬件资源,如内存和I/O性能。使用更快的存储,如SSD,也可以提高性能。

  12. 避免常见错误:例如,避免在循环中执行查询,这会导致大量的数据库连接和查询。

  13. 定期维护:更新统计信息,重建或优化索引,以保持数据库性能。

  14. 考虑使用缓存:例如,使用查询缓存或外部缓存(如Redis或Memcached)来缓存热点数据。

  15. 持续监控和学习:使用监控工具持续监控数据库性能,并随着技术和最佳实践的发展保持学习。

结合这些策略和方法,你可以有效地优化SQL查询,提高数据库性能。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/521946.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

vSphere 8考试认证题库 2024最新(VCP 8.0版本)

VMware VCP-DCV&#xff08;2V0-21.23&#xff09;认证考试题库&#xff0c;已全部更新&#xff0c;答案已经完成校对&#xff0c;完整题库请扫描上方二维码访问。正常考可以考到450分以上&#xff08;满分500分&#xff0c;300分通过&#xff09; An administrator is tasked …

RFID技术进阶:频段选择的艺术与科学

RFID技术进阶&#xff1a;频段选择的艺术与科学 在数字化、自动化的浪潮中&#xff0c;RFID&#xff08;无线射频识别&#xff09;技术以其独特的优势&#xff0c;逐渐在多个领域占据了一席之地。RFID&#xff08;Radio Frequency Identification&#xff09;&#xff0c;即无…

Linux——进程信号(一)

目录 1、信号入门 1.1、技术应用角度的信号 1.2、注意 1.3、信号概念 1.4、用kill -l命令可以查看系统定义的信号列表 1.5、信号处理常见方式概览 2、产生信号 2.1通过终端按键产生信号 Core Dump 2.2、调用系统函数向进程发信号 2.3、由软条件产生信号 3、总结思考…

遥遥领先!基于transformer变体的时间序列预测新SOTA!

目前&#xff0c;以CNN、RNN和 Transformer 模型为代表的深度学习算法已经超越了传统机器学习算法&#xff0c;成为了时间序列预测领域一个新的研究趋向。这其中&#xff0c;基于Transformer架构的模型在时间序列预测中取得了丰硕的成果。 Transformer模型因其强大的序列建模能…

类和对象(1)(至尊详解版)

相信对于大家而言&#xff0c;对于类和对象都会是一头雾水吧&#xff01;什么是类&#xff1f;或者你有对象吗&#xff1f;那么本期的内容呢&#xff1f;就由我来为大家再次增加对于它们的理解&#xff0c;由于水平上的原因&#xff0c;可能会存在不当之处&#xff0c;敬请读者…

测试环境搭建整套大数据系统(九:docker学习)

一&#xff1a;为什么学习dockder&#xff1f; 对于组件的搭建和部署&#xff0c;可以简化。 二&#xff1a;什么是docker&#xff1f; docker是一个平台。 三&#xff1a;怎么使用docker&#xff1f; 1. 安装&#xff0c;切换仓库。 安装 curl -fsSL https://test.docke…

MATLAB2020a安装编译器mingw-64(6.3.0)

MATLAB2020a指定安装mingw-64&#xff08;6.3.0&#xff09;版本编译器 记录一下几个要点 mingw-64&#xff08;6.3.0&#xff09; 找到对应的mingw-64安装包 设置mingw的bin文件路径到环境变量 变量名&#xff1a;MW_MINGW64_LOC MATLAB设置路径

c# combox 行间距调整

初始化combox comboBox1.DropDownStyle ComboBoxStyle.DropDownList;comboBox1.ItemHeight 25; // 设置 combox 的行高comboBox1.DrawMode DrawMode.OwnerDrawVariable; 添加 DrawItem 事件 private void comboBox1_DrawItem(object sender, DrawItemEventArgs e){if (…

接口自动化测试用例的编写方法

&#x1f345; 视频学习&#xff1a;文末有免费的配套视频可观看 &#x1f345; 关注公众号【互联网杂货铺】&#xff0c;回复 1 &#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;涨薪更快 phpunit 接口自动化测试系列 Post接口自动化测试用例 Post方式…

洛谷 P8816 [CSP-J 2022] 上升点列(T4)

目录 题目传送门 算法解析 最终代码 提交结果 尾声 题目传送门 [CSP-J 2022] 上升点列 - 洛谷https://www.luogu.com.cn/problem/P8816 算法解析 k 0 且 xi, yi 值域不大时&#xff0c;这题是非常简单的 DP&#xff0c;类似「数字三角形」。 记 dp(x,y) 为「以 (x,y) …

【生态适配】亚信安慧AntDB数据库与OpenCloudOS、TencentOS Server五款产品完成兼容互认

日前&#xff0c;亚信安慧AntDB数据库与OpenCloudOS8、OpenCloudOS9、TencentOS Server 2、TencentOS Server 3、TencentOS Server 4五款操作系统完成兼容互认。经过严格测试&#xff0c;亚信安慧AntDB数据库与这五款操作系统兼容良好&#xff0c;整体运行稳定。 图1&#xff1…

代理IP以及动态拨号VPS的关系是什么?

在数字时代&#xff0c;网络安全和隐私保护已成为全球关注的热点话题。代理IP和动态拨号VPS作为提升网络匿名性和安全的重要技术&#xff0c;它们在维护网络隐私中扮演着至关重要的角色。虽然这两种技术在表面上看似相似&#xff0c;实际上它们在功能、应用场景以及用户需求满足…