首页 > 数据库 >千万级数据的表,我把慢sql优化后性能提升30倍!

千万级数据的表,我把慢sql优化后性能提升30倍!

时间:2023-08-02 13:45:24浏览次数:36  
标签:占用 30 千万级 索引 sql date 数据 first

分享技术,用心生活


背景:系统中有一个统计页面加载特别慢,前端设置的40s超时时间都加载不出来数据,因为是个统计页面,基本上一猜就知道是mysql的语句有问题,遗留了很久没有解决,正好趁不忙的时候,下定决心一定把它给搞定!


1. 分析原因

(mysql5.7)
执行一下问题sql,可以看到单表查就需要61s 这怎么能忍受?

通过explain看一下执行计划

挑重点,可以看到用命中了名为idx_first_date的索引,但是rows中扫描了1000多万行的数据,这显然是sql慢的根源。我们来查一下表数据量:

真真的千万级的大表!

找到原因后,那么就需要明确优化方向

  • 通过设置分区
  • 通过水平分表
  • 通过优化sql

我们大概会有以上三种思路

分区方案会有诸多限制,比如可能会索引失效,占用内存,有主键限制等,故不采纳

分表方案看来可行,通过缩小热点数据,把非热点数据全部放入分表。是可以达到效果。不过查询表写入日期后,发现最早在2021年。目前系统内查询统计还会经常用到2021年数据。如果贸然分表后,带来的连表查询,数据管理问题等,现有代码可能会出大问题。

那么就只剩下优化sql这一条路了,虽然是千万级数据的表,但是你要相信mysql是可以支撑的。

确定方向后,那就需要解决如何通过减少数据的扫描来实现提升性能。

通过sql可以看到,这个统计sql是根据日期查询的,而且也命中了索引,那么为什么还会扫描这么多数据呢?我们再去看下表的索引

发现猫腻了吧,idx_first_date是个联合索引,再根据上图key_len长度为67和最左匹配原则可知,mysql执行器是优先使用customer_id去扫描数据。所以几乎全表扫描了。

我们把idx_first_date修改一下联合索引的字段顺序,把first_date放在第一位,我们再来执行一下sql看下结果

1.6s!大呼!性能直接提升30倍!

你以为到这里就结束了吗?不不不!再看一张图

发现了吗,因为用了联合索引,导致索引占用空间过大,比数据占用都大。我认为这里存在滥用索引的现象。索引本身不止会占用空间,而且也会降低写入性能,维护更新索引成本过高等。

idx_first_date中的customer_id字段去掉,再看下索引占用情况

下降至2.6G,减少了将近1.4G的索引占用。
至此,这张千万数据的大表慢sql已优化完,不仅提升了查询性能,也减少了索引带来的空间占用过大的问题。

本文由mdnice多平台发布

标签:占用,30,千万级,索引,sql,date,数据,first
From: https://www.cnblogs.com/douzige/p/17600447.html

相关文章

  • mysql在执行innobackupex增量备份时报错cannot open *****/xtrabackup_checkpoints
    问题描述:mysql在执行innobackupex增量备份时报错cannotopen*****/xtrabackup_checkpoints,如下所示:数据库:mysql5.7.21说明:此次测试环境为从节点.1、异常重现[mysql@mysql-leo-perslave~]$/usr/bin/innobackupex--defaults-file=/home/mysql/etc/my.cnf--socket=/mysql/da......
  • SQL Server 内存占用较高 - 清除缓存 或 设置内存最大占用值
    SQLServer对服务器内存的使用策略是用多少内存就占用多少内存,只用在服务器内存不足时,才会释放一点占用的内存,所以SQLServer服务器内存往往会占用很高查看内存状态:DBCCMemoryStatus这些内存一般都是SqlServer运行时候用作缓存的:数据缓存:执行查询语句,SqlServer会将相......
  • MySQL8_SQL语法
    MySQL8_SQL语法SQL全称StructuredQueryLanguage,结构化查询语言。操作关系型数据库的编程语言,定义了一套操作关系型数据库统一标准。 一、SQL通用语法在学习具体的SQL语句之前,先来了解一下SQL语言的同于语法。1).SQL语句可以单行或多行书写,以分号结尾。2).SQL语句可......
  • 主题:ThinkPad SL300 SL400 SL500 Vista Ultimate 32位 S
    主题:ThinkPadSL300SL400SL500VistaUltimate32位SP1帆帆hgdsA32F73FF21166E5937AE10E5CAFF5AB4boot1of3.iso3D8755C28D7536AE5E1DAD321A6400E646R5190vu32.iso003914E399306F7C8D251334D1BD2C293-2of2.iso5356474545DB70438B01FA4E2......
  • 因MySQL数据库无法启动导致LiteCVR视频平台也无法启动的问题解决教程
    近期呢,我们的数据人员发现有时候MySQL数据库无法启动会导致LiteCVR视频平台也无法启动,所以接下来我们将为大家讲解遇见这种问题时的解决教程。但是在这之前值得一提的一件事那就是我们的LiteCVR平台默认的数据库是SQLite,不过用户可以根据自己的使用需求选择将数据库切换为MySQL。具......
  • SQL Server导出存储过程
    sqlserver批量导出视图selecttextfromsyscommentss1joinsysobjectss2ons1.id=s2.idwherextype='V'sqlserver批量导出存储过程selecttextfromsyscommentss1joinsysobjectss2ons1.id=s2.idwherextype='P'sqlserver批量导出函数selecttex......
  • .NET+MySQL的坑
    #JSON字段访问时,引号格式--需要替换C#里的""\""""为"\""--C#里的SQL代码rtrim(ltrim(REPLACE(JSON_EXTRACT(b.yarn_type_id,'$.dye_name'),""\"""",'')))--MySQL直接执行的代码rtri......
  • 火山引擎ByteHouse:云原生数据库如何提升MySQL兼容性?
    更多技术交流、求职机会,欢迎关注字节跳动数据平台微信公众号,回复【1】进入官方交流群当前各类软件层出不穷,单独某一款软件往往难以满足企业应用需求,一般都需要与各类软件组合使用,这时软件生态兼容性就显得格外重要。作为关系数据库管理系统的代表之一,MySQL支持大多数操作系统、编程......
  • 求和计算MySQL中如何对两列求和(mysql 中两列总和)
    求和计算:MySQL中如何对两列求和?在MySQL数据库中,对两列进行求和运算是一项常规操作。本文将介绍在MySQL中如何对两列进行求和运算,并给出相关的SQL代码示例。SQL语句中使用的SUM()函数是MySQL中常用的聚合函数之一,用于计算某一列的总和。而对于两列的求和,则需要将两个......
  • PostgreSQL-pg_upgrade 大版本升级14.7-15.2
    文档参考pg_upgrade1大纲pg_upgrade-boldbindir-Bnewbindir-doldconfigdir-Dnewconfigdir[option...]2描述PG_UPGRADE(以前称为PG_Migrator)允许将存储在PostgreSQL数据文件中的数据升级到较新的PostgreSQL主要版本,而无需进行主要版本升级通常所需的数据转储/恢复,例如......