一条SQL引起的系统不可用

news2024/11/20 11:47:18

一.前言

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

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

select
  count(1) as cnt,
  user_tag_user_life_period as label_value,
  'user_tag_user_life_period' as label_english
from
  data_tag.tag_user_attribute_all
where
  one_id global in (
    select
      one_id
    from
      data_dwd.big_table final
    where
      (
        (
          case
            when reg_time_taxfree is not null then 1
            else 0
          end
        ) + (
          case
            when reg_time_hotel is not null then 1
            else 0
          end
        ) + (
          case
            when reg_time_travel is not null then 1
            else 0
          end
        ) + (
          case
            when reg_time_invest is not null then 1
            else 0
          end
        )
      ) >= 2
  )
group by
  user_tag_user_life_period
having
  user_tag_user_life_period is not null
  and user_tag_user_life_period <> ''
order by
  cnt desc
limit
  1
union all
select
  count(1) as cnt,
  user_tag_level_name_taxfree as label_value,
  'user_tag_level_name_taxfree' as label_english
from
  data_tag.tag_user_attribute_all
where
  one_id global in (
    select
      one_id
    from
      data_dwd.big_table final
    where
      (
        (
          case
            when reg_time_taxfree is not null then 1
            else 0
          end
        ) + (
          case
            when reg_time_hotel is not null then 1
            else 0
          end
        ) + (
          case
            when reg_time_travel is not null then 1
            else 0
          end
        ) + (
          case
            when reg_time_invest is not null then 1
            else 0
          end
        )
      ) >= 2
  )
group by
  user_tag_level_name_taxfree
having
  user_tag_level_name_taxfree is not null
  and user_tag_level_name_taxfree <> ''
order by
  cnt desc
limit
  1
union all
select
  count(1) as cnt,
  user_tag_level_name_travel as label_value,
  'user_tag_level_name_travel' as label_english
from
  data_tag.tag_user_attribute_all
where
  one_id global in (
    select
      one_id
    from
      data_dwd.big_table final
    where
      (
        (
          case
            when reg_time_taxfree is not null then 1
            else 0
          end
        ) + (
          case
            when reg_time_hotel is not null then 1
            else 0
          end
        ) + (
          case
            when reg_time_travel is not null then 1
            else 0
          end
        ) + (
          case
            when reg_time_invest is not null then 1
            else 0
          end
        )
      ) >= 2
  )
group by
  user_tag_level_name_travel
having
  user_tag_level_name_travel is not null
  and user_tag_level_name_travel <> ''
order by
  cnt desc
limit
  1
union all
select
  count(1) as cnt,
  user_tag_level_name_hotel as label_value,
  'user_tag_level_name_hotel' as label_english
from
  data_tag.tag_user_attribute_all
where
  one_id global in (
    select
      one_id
    from
      data_dwd.big_table final
    where
      (
        (
          case
            when reg_time_taxfree is not null then 1
            else 0
          end
        ) + (
          case
            when reg_time_hotel is not null then 1
            else 0
          end
        ) + (
          case
            when reg_time_travel is not null then 1
            else 0
          end
        ) + (
          case
            when reg_time_invest is not null then 1
            else 0
          end
        )
      ) >= 2
  )
group by
  user_tag_level_name_hotel
having
  user_tag_level_name_hotel is not null
  and user_tag_level_name_hotel <> ''
order by
  cnt desc
limit
  1
union all
select
  count(1) as cnt,
  user_tag_taxfree_and_travel_sex as label_value,
  'user_tag_taxfree_and_travel_sex' as label_english
from
  data_tag.tag_user_attribute_all
where
  one_id global in (
    select
      one_id
    from
      data_dwd.big_table final
    where
      (
        (
          case
            when reg_time_taxfree is not null then 1
            else 0
          end
        ) + (
          case
            when reg_time_hotel is not null then 1
            else 0
          end
        ) + (
          case
            when reg_time_travel is not null then 1
            else 0
          end
        ) + (
          case
            when reg_time_invest is not null then 1
            else 0
          end
        )
      ) >= 2
  )
group by
  user_tag_taxfree_and_travel_sex
having
  user_tag_taxfree_and_travel_sex is not null
  and user_tag_taxfree_and_travel_sex <> ''
order by
  cnt desc
limit
  1
union all
select
  count(1) as cnt,
  user_tag_taxfree_and_travel_user as label_value,
  'user_tag_taxfree_and_travel_user' as label_english
from
  data_tag.tag_user_attribute_all
where
  one_id global in (
    select
      one_id
    from
      data_dwd.big_table final
    where
      (
        (
          case
            when reg_time_taxfree is not null then 1
            else 0
          end
        ) + (
          case
            when reg_time_hotel is not null then 1
            else 0
          end
        ) + (
          case
            when reg_time_travel is not null then 1
            else 0
          end
        ) + (
          case
            when reg_time_invest is not null then 1
            else 0
          end
        )
      ) >= 2
  )
group by
  user_tag_taxfree_and_travel_user
having
  user_tag_taxfree_and_travel_user is not null
  and user_tag_taxfree_and_travel_user <> ''
order by
  cnt desc
limit
  1
union all
select
  count(1) as cnt,
  user_tag_taxfree_and_hotel_sex as label_value,
  'user_tag_taxfree_and_hotel_sex' as label_english
from
  data_tag.tag_user_attribute_all
where
  one_id global in (
    select
      one_id
    from
      data_dwd.big_table final
    where
      (
        (
          case
            when reg_time_taxfree is not null then 1
            else 0
          end
        ) + (
          case
            when reg_time_hotel is not null then 1
            else 0
          end
        ) + (
          case
            when reg_time_travel is not null then 1
            else 0
          end
        ) + (
          case
            when reg_time_invest is not null then 1
            else 0
          end
        )
      ) >= 2
  )
group by
  user_tag_taxfree_and_hotel_sex
having
  user_tag_taxfree_and_hotel_sex is not null
  and user_tag_taxfree_and_hotel_sex <> ''
order by
  cnt desc
limit
  1
union all
select
  count(1) as cnt,
  user_tag_taxfree_and_hotel_user as label_value,
  'user_tag_taxfree_and_hotel_user' as label_english
from
  data_tag.tag_user_attribute_all
where
  one_id global in (
    select
      one_id
    from
      data_dwd.big_table final
    where
      (
        (
          case
            when reg_time_taxfree is not null then 1
            else 0
          end
        ) + (
          case
            when reg_time_hotel is not null then 1
            else 0
          end
        ) + (
          case
            when reg_time_travel is not null then 1
            else 0
          end
        ) + (
          case
            when reg_time_invest is not null then 1
            else 0
          end
        )
      ) >= 2
  )
group by
  user_tag_taxfree_and_hotel_user
having
  user_tag_taxfree_and_hotel_user is not null
  and user_tag_taxfree_and_hotel_user <> ''
order by
  cnt desc
limit
  1
union all
select
  count(1) as cnt,
  user_tag_last_year_amount as label_value,
  'user_tag_last_year_amount' as label_english
from
  data_tag.tag_user_attribute_all
where
  one_id global in (
    select
      one_id
    from
      data_dwd.big_table final
    where
      (
        (
          case
            when reg_time_taxfree is not null then 1
            else 0
          end
        ) + (
          case
            when reg_time_hotel is not null then 1
            else 0
          end
        ) + (
          case
            when reg_time_travel is not null then 1
            else 0
          end
        ) + (
          case
            when reg_time_invest is not null then 1
            else 0
          end
        )
      ) >= 2
  )
group by
  user_tag_last_year_amount
having
  user_tag_last_year_amount is not null
  and user_tag_last_year_amount <> ''
order by
  cnt desc
limit
  1
union all
select
  count(1) as cnt,
  user_tag_last_year_frequency as label_value,
  'user_tag_last_year_frequency' as label_english
from
  data_tag.tag_user_attribute_all
where
  one_id global in (
    select
      one_id
    from
      data_dwd.big_table final
    where
      (
        (
          case
            when reg_time_taxfree is not null then 1
            else 0
          end
        ) + (
          case
            when reg_time_hotel is not null then 1
            else 0
          end
        ) + (
          case
            when reg_time_travel is not null then 1
            else 0
          end
        ) + (
          case
            when reg_time_invest is not null then 1
            else 0
          end
        )
      ) >= 2
  )
group by
  user_tag_last_year_frequency
having
  user_tag_last_year_frequency is not null
  and user_tag_last_year_frequency <> ''
order by
  cnt 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.coloradmin.cn/o/1500462.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【网络连接】ping不通的常见原因+解决方案,如何在只能访问网关时诊断,并修复IP不通的问题

【网络连接】ping不通的常见原因解决方案&#xff0c;如何在只能访问网关时诊断&#xff0c;并修复IP不通的问题 写在最前面网络基础可能的问题、表现以及解决方案如何诊断和解决操作步骤 详细问题描述详细解决方案1. 防火墙或安全软件拦截2. IP配置错误3. 网络设备问题4. 物理…

2024 GoLand激活,分享几个GoLand激活的方案

文章目录 GoLand公司简介我这边使用GoLand的理由GoLand 最新变化GoLand 2023.3 最新变化AI Assistant 正式版GoLand 中的 AI Assistant&#xff1a;_Rename_&#xff08;重命名&#xff09;GoLand 中的 AI Assistant&#xff1a;_Write documentation_&#xff08;编写文档&…

MySql 组合索引的使用

MySql 组合索引的使用 测试Mysql组合索引在不同的查询条件组合下的索引使用情况。当有abc 3个字的的组合索引时&#xff0c;按照MySql 的左匹配原则&#xff0c;abc&#xff0c;ab&#xff0c;a 是满足左匹配原则&#xff0c;肯定是会走索引的&#xff0c;但是其他的场景&…

【PCL】(二十六)自定义条件的欧几里得聚类分割点云

&#xff08;二十六&#xff09;自定义条件的欧几里得聚类分割点云 以下代码实现自定义条件对点进行欧几里得聚类分割。 conditional_euclidean_clustering.cpp #include <pcl/point_types.h> #include <pcl/io/pcd_io.h> #include <pcl/console/time.h>#…

鞋服品牌怎样合理把控订货深度和宽度

在鞋服品牌的运营管理中&#xff0c;订货深度和宽度是两个至关重要的概念。订货深度指的是某一款式或规格的产品数量&#xff0c;而订货宽度则代表品牌所涵盖的产品种类和款式。合理把控订货深度和宽度对于品牌的库存管理、销售情况以及顾客满意度都有着深远的影响。本文将探讨…

【Linux】 yum —— Linux 的软件包管理器

Linux 的软件包管理器 yum yum 是什么什么是软件包查看软件包 yum 命令行工具yum 配置文件yum 凭什么可以支持下载呢&#xff1f;yum 生态yum 社区yum 的故障排除和资源支持yum 的持续集成和持续交付 yum 是什么 Yum&#xff08;Yellowdog Updater Modified&#xff09;是一个…

洛谷 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) …

GaussDB(DWS)运维利刃:TopSQL工具解析

在生产环境中&#xff0c;难免会面临查询语句出现异常中断、阻塞时间长等突发问题&#xff0c;如果没能及时记录信息&#xff0c;事后就需要投入更多的人力及时间成本进行问题的定位和解决&#xff0c;有时还无法定位到错误出现的地方。在本期《GaussDB(DWS)运维利刃&#xff1…

Dubbo基础入门二

8、Dubbo协议 服务调用 8.1 服务端 启动过程深入分析 我们查看一下服务启动的过程 ProtocolFilterWrapper.export 好我们进入DubboProtocol.export 创建服务 分析我们的Handler 我们接着返回刚才位置 下面的super方法里面会创建服务&#xff0c;ChannelHandlers.wrap会对hand…

套接字编程 --- 一

目录 1. 预备知识 1.1. 端口号 1.2. 认识TCP协议 1.3. 认识UDP协议 1.4. 网络字节序 2. socket 2.1. socket 常见系统调用 2.1.1. socket 系统调用 2.1.2. bind 系统调用 2.1.3. recvfrom 系统调用 2.1.4. sendto系统调用 2.3. 其他相关接口 2.3.1. bzero 2.3.2…

代码随想录算法训练营第day10|232.用栈实现队列、 225. 用队列实现栈

目录 a.232.用栈实现队列 b. 225. 用队列实现栈 a.232.用栈实现队列 题目链接 请你仅使用两个栈实现先入先出队列。队列应当支持一般队列支持的所有操作&#xff08;push、pop、peek、empty&#xff09;&#xff1a; 实现 MyQueue 类&#xff1a; void push(int x) 将元素…

专题一 - 双指针 - leetcode 202. 快乐数 | 简单难度

leetcode 202. 快乐数 leetcode 202. 快乐数 | 简单难度1. 题目详情1. 原题链接2. 基础框架 2. 解题思路1. 题目分析2. 算法原理3. 时间复杂度 3. 代码实现4. 知识与收获 leetcode 202. 快乐数 | 简单难度 1. 题目详情 编写一个算法来判断一个数 n 是不是快乐数。 「快乐数」…

掼蛋的牌型与规律(上篇)

掼蛋是一项配合类的棋牌竞技游戏&#xff0c;掼蛋的最大魅力以及最集中的特点在于变化&#xff0c;在于组牌的变数。有的掼蛋新手往往先把牌配死&#xff0c;并且直接决定好出牌计划&#xff0c;然后守株待兔。掼蛋的取胜之道在于静态组合加上动态变化。本文主要介绍一下掼蛋的…

【广度优先搜索】【图论】【并集查找】2493. 将节点分成尽可能多的组

作者推荐 视频算法专题 本文涉及知识点 广度优先搜索 图论 并集查找 LeetCod2493. 将节点分成尽可能多的组 给你一个正整数 n &#xff0c;表示一个 无向 图中的节点数目&#xff0c;节点编号从 1 到 n 。 同时给你一个二维整数数组 edges &#xff0c;其中 edges[i] [ai…

神州大地人类来源猜想

在公元前2000年以前&#xff0c;伟大的中华民族还是石器时代&#xff0c;我们有很多美好的神话和传说&#xff0c;三皇五帝就是这个时代伟大部落或者部落首领的故事。 关于人类的历史&#xff0c;从基因学上最新的研究成果大概是这样的&#xff0c;虽然从300万年前就诞生了人类…

3D资产管理

3D 资产管理是指组织、跟踪、优化和分发 3D 模型和资产以用于游戏、电影、AR/VR 体验等各种应用的过程。 3D资产管理也称为3D内容管理。 随着游戏、电影、建筑、工程等行业中 3D 内容的增长&#xff0c;实施有效的资产管理工作流程对于提高生产力、减少错误、简化工作流程以及使…

Xinstall微信调起APP,提升用户体验与转化率

在移动互联网时代&#xff0c;APP已经成为人们日常生活中不可或缺的一部分。然而&#xff0c;随着市场竞争的加剧&#xff0c;如何让用户更便捷地使用APP&#xff0c;提高分享营销的下载转化率&#xff0c;成为了开发者们亟待解决的问题。今天&#xff0c;我们将向大家介绍一款…

C/C++的内存管理与初阶模板

引言 我们在学习C的时候&#xff0c;会经常在堆上申请空间&#xff0c;所以这个时候就体现了内存管理遍历。 图下是我们常见的计算机的内存划分&#xff1a; 我也在图下对部分变量存在的位置&#xff0c;及时标注。(如果有任何问题可以联系博主修改&#xff0c;感谢大家。) 那…

如何在Windows上使用Docker,搭建一款实用的个人IT工具箱It- Tools

文章目录 1. 使用Docker本地部署it-tools2. 本地访问it-tools3. 安装cpolar内网穿透4. 固定it-tools公网地址 本篇文章将介绍如何在Windows上使用Docker本地部署IT- Tools&#xff0c;并且同样可以结合cpolar实现公网访问。 在前一篇文章中我们讲解了如何在Linux中使用Docker搭…

Docker安装主从数据库

首先开启docker后直接执行命令 docker run -d \ -p 3307:3306 \ -v /xk857/mysql/master/conf:/etc/mysql/conf.d \ -v /xk857/mysql/master/data:/var/lib/mysql \ -e MYSQL_ROOT_PASSWORD123456 \ --name mysql-master \ mysql:8.0.29 默认情况下MySQL的binlog日志是自动开…