一条SQL引起的系统不可用

一.前言

最近在运维系统,系统对客端突然报了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查询,提高数据库性能。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Android 14后台服务永久保活的技术方法

Android 14后台服务永久保活的技术方法 在本篇博客中&#xff0c;我们将探讨如何创建一个在Android系统中不会被杀死的后台服务。 第一步&#xff1a;创建一个后台服务。 在这一步中&#xff0c;我们需要创建一个后台服务的代码。 第二步&#xff1a;在AndroidManifest.xml中…

StarRocks实战——vivo基于 StarRocks 构建实时大数据平台

目录 前言 一、数据挑战 1.1 时效性挑战&#xff0c;业务分析决策需加速 1.2 访问量挑战&#xff0c;性能与稳定性亟待提高&#xff0c;支撑业务稳定运行 1.3 计算场景挑战&#xff0c;难以满足业务复杂查询需求 1.4. 运维挑战&#xff0c;用户查询体验需优化 二、OLA…

docker的网络配置

文章目录 1、网络模式1.1、bridge模式(默认模式)1.2、host模式 2、bridge模式3、自定义网络 1、网络模式 Docker在创建容器时有四种网络模式&#xff1a;bridge/host/container/none&#xff0c;bridge为默认不需要用–net去指定&#xff0c;其他三种模式需要在创建容器时使用…

Spring(22) Spring中的9种设计模式

目录 一、简单工厂模式&#xff08;Simple Factory&#xff09;二、工厂方法模式&#xff08;Factory Method&#xff09;三、单例模式&#xff08;Singleton&#xff09;四、适配器模式&#xff08;Adapter&#xff09;五、代理模式&#xff08;Proxy&#xff09;七、观察者模…

洛谷p1225 c++(使用高精度)

题解: 一开始我这个代码想到的是使用递归来求解 int digui(int n){int sum=0;if(n==1)sum=1;if(n==2)sum=2;if(n==1||n==2)return sum;if(n>2){return sum+=digui(n-1)+digui(n-2);} } 但是后面发现明显超时,我试图用记忆化搜索来抢救一下,所以就有了下面代码 int di…

前端食堂技术周刊第 114 期:Interop 2024、TS 5.4 RC、2 月登陆浏览器的新功能、JSR、AI SDK 3.0

美味值&#xff1a;&#x1f31f;&#x1f31f;&#x1f31f;&#x1f31f;&#x1f31f; 口味&#xff1a;凉拌鸡架 食堂技术周刊仓库地址&#xff1a;https://github.com/Geekhyt/weekly 大家好&#xff0c;我是童欧巴。欢迎来到前端食堂技术周刊&#xff0c;我们先来看下…

Github 2024-03-05 Python开源项目日报 Top10

根据Github Trendings的统计&#xff0c;今日(2024-03-05统计)共有10个项目上榜。根据开发语言中项目的数量&#xff0c;汇总情况如下&#xff1a; 开发语言项目数量Python项目10TypeScript项目1 稳定扩散Web UI 创建周期&#xff1a;512 天开发语言&#xff1a;Python协议类…

数仓实战——京东数据指标体系的构建与实践

目录 一、如何理解指标体系 1.1 指标和指标体系的基本含义 1.2 指标和和标签的区别 1.3 指标体系在数据链路中的位置和作用 1.4 流量指标体系 1.5 指标体系如何向上支撑业务应用 1.6 指标体系背后的数据加工逻辑 二、如何搭建和应用指标体系 2.1 指标体系建设方法—OS…

eclipse搭建java web项目

准备条件 eclipsejdk1.8 &#xff08;配置jdk环境&#xff09;apache-tomcat-8.5.97&#xff08;记住安装位置&#xff09; 一 点击完成 开始创建javaweb项目 import java.io.IOException; import java.io.PrintWriter;import javax.servlet.ServletException; import javax.s…

IP传输方式——组播

组播作为IP传输三种方式之一&#xff0c;指的是报文从一个源发出&#xff0c;被转发到一组特定的接收者&#xff0c;相同的报文在每条链路上最多有一份。相较于传统的单播和广播&#xff0c;组播可以有效地节约网络带宽、降低网络负载&#xff0c;所以被广泛应用于IPTV、实时数…

深度学习-Pytorch实现经典VGGNet网络

深度学习-Pytorch实现经典VGGNet网络 深度学习中&#xff0c;经典网络引领一波又一波的技术革命&#xff0c;从LetNet到当前最火的GPT所用的Transformer&#xff0c;它们把AI技术不断推向高潮。2012年AlexNet大放异彩&#xff0c;它把深度学习技术引领第一个高峰&#xff0c;打…

如何利用Flutter来写后端 服务端应用

前言 Flutter是谷歌推出的一款跨平台开发框架&#xff0c;现在属于此领域star最多的框架&#xff0c;其被广泛应用于构建前台界面&#xff0c;但或许很少人知道&#xff0c;他也可以写后端应用。 本文主角 flutter非常著名的getx库推出的get server jonataslaw/get_server:…

广播、组播域套接字的实现

思维导图&#xff1a; 广播模式&#xff1a; 发送端&#xff1a; #include <myhead.h> int main(int argc, const char *argv[]) {//创建套接字int sfdsocket(AF_INET,SOCK_DGRAM,0);if(sfd-1){perror("socket error");return -1;}//设置套接字允许广播属性i…

VS2022连接数据库以及常用的连接函数

下面是如何配置以及设置VS2022连接数据库 第一步:打开mysql的安装目录&#xff0c;默认安装目录如下&#xff1a;C:\Program Files\MySQL\MySQL Server 8.0&#xff0c;确认 lib 目录和include 目录是否存在。 第二步&#xff1a;打开VS2019&#xff0c;新建一个空工程,控制台…

STM32 | STM32时钟分析、GPIO分析、寄存器地址查找、LED灯开发(第二天)

STM32 第二天 一、 STM32时钟分析 寄存器&#xff1a;寄存器的功能是存储二进制代码&#xff0c;它是由具有存储功能的触发器组合起来构成的。一个触发器可以存储1位二进制代码&#xff0c;故存放n位二进制代码的寄存器&#xff0c;需用n个触发器来构成 在计算机领域&#x…

远程桌面连接不上服务器怎么办?

在进行远程桌面连接时&#xff0c;有时候会遇到连接不上服务器的问题&#xff0c;这给我们的工作和生活带来了很多不便。下面&#xff0c;我们来了解一下解决这个问题的方法和工具。 【天联】组网的介绍 【天联】组网是一款异地组网内网穿透产品&#xff0c;由北京金万维科技有…

快速上手:在 Android 设备上运行 Pipy

Pipy 作为一个高性能、低资源消耗的可编程代理&#xff0c;通过支持多种计算架构和操作系统&#xff0c;Pipy 确保了它的通用性和灵活性&#xff0c;能够适应不同的部署环境&#xff0c;包括但不限于云环境、边缘计算以及物联网场景。它能够在 X86、ARM64、海光、龙芯、RISC-V …

Linux网络编程 ——UDP 通信

Linux网络编程 ——UDP 通信 1. UDP1.1 UDP 通信1.2 广播1.3 组播&#xff08;多播&#xff09; 2. 本地套接字 1. UDP 1.1 UDP 通信 输入 man 2 sendto 查看说明文档 #include <sys/types.h> #include <sys/socket.h>ssize_t sendto(int sockfd, const void *buf…

GlusterFS系统内核调优

转载说明&#xff1a;如果您喜欢这篇文章并打算转载它&#xff0c;请私信作者取得授权。感谢您喜爱本文&#xff0c;请文明转载&#xff0c;谢谢。 相关文章&#xff1a; 分布式存储——GlusterFS 关于GlusterFS的卷 GlusterFS—新手陷阱 GlusterFS常用命令集 前言 本文总…

深度学习预测分析API:金融领域的Game Changer

&#x1f680; 引言 在这个AI遍地开花的时代&#xff0c;谁能成为金融领域的真正Game Changer&#xff1f;那必然是是深度学习预测分析API。如大脑般高效运转的系统不仅颠覆了传统操作&#xff0c;更是以无与伦比的速度和精度赋予了金融数据以全新的生命。 &#x1f4bc; 广泛…