如何用分布式数据库解决慢查询问题

当使用MySQL时,我们不可避免地会遇到许多与慢查询相关的问题。

为了解决这些慢SQL的问题,我们通常需要投入大量的精力去研究执行计划、考虑合适的索引策略、精心改写SQL语句,甚至可能需要调整程序逻辑。然而,针对特定SQL的优化往往既复杂又具有挑战性,而且存在许多原因,即使经过多次尝试和优化,也可能无法取得显著的效果。

慢查询产生的典型场景

下面是2个典型的慢查询场景,大家在日常写SQL和优化SQL的过程中应该会有感受:

场景一:大表

这是MySQL的经典问题。MySQL早期有单表数据量不能超过2000W的说法,虽然有点夸张,不过对于MyQL中千万级,乃至过亿的表,哪怕对这种表的查询建了索引,索引的B+树也会很深,查询速度确实很受影响,从而形成慢SQL。

一些有经验的开发会考虑给这张表加分区,通过合理拆分,来降低每个分区对应B+树索引的深度,从而提升执行性能。但MySQL毕竟是一个单机库,各个分区共享的还是一份硬件资源;而如果想突破单机的限制,就要考虑做分库,而那又是一个更复杂的问题,涉及到整个数据库用法和结构的大调整。

场景二:多表连接。这也是让很多研发头痛的问题,类似下面这类SQL:

select ... 

from t1 --100行

left join t2 --100000行

on t1.c1=t2.c1

left join t3 --100行

on t1.c1=t3.c1

left join t4 --100行

on t1.c1=t4.c1

order by t1.c1 limit 1000;

在这个例子中, 4 张表做连接 T1、T2、T3、T4,其中 T2 是大表,其它都是小表,如果严格按照连接次序来做,T1 跟 T2 连接,再跟 T3、T4 连接,最大的表T2就过早进行了合并,导致结果集特别大,整个SQL开销相对较高。

如果要优化慢查询的话,就要改写SQL,把T2挪到最后来连接,这样整个SQL的代价就会小很多了,但很多时候这是跟我们业务开发的逻辑是违背的。很多场景下,修改SQL都是非常麻烦的一件事。

其实自适应调整表连接顺序应该是数据库能做到的,这步一般被称为“SQL改写”,但因为MySQL当前的优化器更多是基于规则的模型,所以通常情况是做不到这点的。

为什么MySQL的大SQL能力比较差?

因为MySQL社区主要还是将MySQL定位为一个纯粹OLTP(Online Transaction Processing,联机交易处理)型的开源数据库。这个定位使得MySQL的迭代发版,侧重于提升单核性能、加强事务处理能力等,而对于大数据量、复杂查询类的偏OLAP(Online Analytical Processing,联机事务处理)场景,MySQL发展缓慢。

举个例子:在MySQL 8.0.14前,MySQL是没有并行执行能力的。也就是说MySQL对每条SQL最多只能使用CPU的一个核来处理。而并行执行可以将一个 SQL 查询任务分成多个子任务,并允许这些子任务在多个处理器上同时运行,以提高整个查询任务的执行效率。对于上文的慢查询场景一而言,并行执行就可以极快加速这种场景的查询效率。虽然MySQL自8.0.14版本开始支持并行执行,但目前仅在select count(*)等有限场景下生效,且必须手动配置参数。因此目前MySQL还不支持大部分场景的并行执行,从根本上解决复杂查询的问题。

用分布式数据库解决慢查询问题

针对这些挑战,OceanBase作为一款原生分布式的HTAP(Hybrid Transactional/Analytical Processing)数据库,对大规模查询场景的处理上进行了重点的优化。如果您也在寻求解决慢SQL查询的方案,不妨尝试一下用分布式数据库OceanBase从根本上来解决这个问题。

OceanBase在大查询场景的主要技术点有:

1、并行执行

OceanBase有非常成熟的并行执行能力,可以对普通查询、DDL、DML操作都进行并行执行,并且可以自动/手动灵活选取并行度。这可以使得开发者通过少量CPU的代价,简单、直接的使原本运行较慢的SQL性能快上几倍,对于大SQL问题有立竿见影的解决效果。

可以通过下面两个参数来开启并设置自动并行:

#开启并行

set global parallel_degree_policy = AUTO; 

#设置基表最大扫描时间,单位为ms,默认为1000ms;您可以视情况调大或调小这个值,这里把这个参数改为100ms,即基表扫描时间超过100ms,则开启并行执行。

set global parallel_min_scan_time_threshold = 100;

2、分库分表

如同前文MySQL的场景一中所提到的,解决大数据量表查询性能问题的一个解法是分库分表,但MySQL分库分表有很高的改造成本。而OceanBase是一款原生的分布式数据库,OceanBase中的分区是一个独立的存储、高可用、事务的单位,这意味着OceanBase同一张表的不同分区可以分布在不同的服务器上,从而利用多机性能大大加快大表查询速度。同时OB的原生分布式能力,也可以使应用程序像使用一个单机数据库一样使用分布式的OB,没有业务改造成本。

3、多表连接次序优化

对于前文的场景二,业务上是比较难判断怎么调整表连接的顺序更好的,而OceanBase 实现了一套完备的连接枚举算法,整体优化逻辑是基于代价的,可以灵活调整内连接和外连接的次序,可以调整外连接、反连接、半连接,甚至还可以改变一个外连接的连接类型,把它变成内连接或反连接等,可以做到场景自动优化。像场景二的例子,在OB中自然就会优化成,t1跟t3连接,再跟t4连接,最后再跟t2连接,从而使得SQL执行性能快了近百倍。很多在MySQL中需要反复改写、调优的SQL,在OB中自然跑出来就是最优的执行计划。

4、子查询场景优化

子查询也是很常见的性能问题,并且不同于多表连接,子查询通常比较难改写,往往会造成执行很慢。OceanBase 查询改写模块,实现了丰富的子查询优化策略,只要不是嵌套非常深的子查询,都可以把它变成连接,变成连接后,就成了连接枚举的问题,可以采取不同的连接算法去优化它。

5、大表聚合场景优化

大表聚合也是一个经典的场景,比如我们要汇总一年的营业额数据,就有可能用到下面的SQL:

SELECT year(sold_date) AS yearDate,  code, name, SUM(value0) as total_value FROM t where sold_date>='2023-01-01' and sold_date<'2023-12-31' GROUP BY year(sold_date), code, name;

针对这种场景,OB有一种优化能力称作预聚合,就是把大表的数据拆成多份,每个线程分别做分组聚合,然后线程交换数据继续聚合,全部聚合完后再做一次汇总。比如把示例中t表分为100组,每组按year(sold_date), code, name分别聚合,再最后汇总。

预聚合配合并行执行,往往可以取得几倍的性能提升。但这种优化并不一定是好效果的,假如一共10亿条数据,不同的year(sold_date), code, name租户就有5亿种,那么区分度就太低了,预聚合甚至是一个反优化。

OceanBase 面对大表聚合场景,是让执行引擎变得更聪明,不在优化器层面去做决策,而是交给执行层,执行根据计算过程中的实际情况,去决定做不做预聚合优化。

当前OceanBase 对各种场景基本都支持了这个优化,包括分组、去重、窗口函数,都可以灵活判断是否做预聚合。

6、TP 与 AP隔离,避免互相影响

对于数据库来说,相比于单条复杂大查询,让大量的 DML 和短查询尽快返回更有意义。为了避免一条大查询阻塞大量简单请求而导致系统吞吐量暴跌,避开分库分表的查询性能局限,当大查询和短请求同时争抢 CPU 时,OceanBase 会限制大查询的 CPU 使用。当一个线程执行的 SQL 查询耗时太长,这条查询就会被判定为大查询,一旦判定为大查询,就会进入大查询队列,然后执行大查询的线程会等在一个 Pthread Condition 上,为其它的租户工作线程让出 CPU 资源。

通过这些技术能力,可以使得原本在MySQL中执行时间超过1s的慢SQL,在OceanBase中获得显著的性能提升。

如果大家希望体验分布式数据库OceanBase在复查查询的性能,可以在OceanBase官网开通365天的免费试用。1核4G的OceanBase租户实例就可以体验查询性能,如果还需要体验OceanBase的其他特性,也可以申请企业版的集群实例。产品中有相关的新手教程引导,也请注意通过上文中的方法打开并行执行。

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

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

相关文章

pipx安装提示找不到包

执行&#xff1a; pipx install --include-deps --force "ansible6.*"WARNING: Retrying (Retry(total4, connectNone, readNone, redirectNone, statusNone)) after connection broken by NewConnectionError(<pip._vendor.urllib3.connection.HTTPSConnection …

VMware 17虚拟Ubuntu 22.04设置共享目录

VMware 17虚拟Ubuntu 22.04设置共享目录 共享文件夹挂载命令&#xff01;&#xff01;&#xff01;<font colorred>配置启动自动挂载Chapter1 VMware 17虚拟Ubuntu 22.04设置共享目录一、卸载老版本二、安装open-vm-tools<font colorred>三、配置启动自动挂载四、添…

Python用CEEMDAN-LSTM-VMD金融股价数据预测及SVR、AR、HAR对比可视化

全文链接&#xff1a;https://tecdat.cn/?p38224 分析师&#xff1a;Duqiao Han 股票市场是一个复杂的非线性系统&#xff0c;股价受到许多经济和社会因素的影响。因此&#xff0c;传统的线性或近线性预测模型很难有效、准确地预测股票指数的价格趋势。众所周知&#xff0c;深…

ubuntu20.04默认的python3.8升级到python3.10

Python 3.8 于 2019 年 10 月发布&#xff0c;距今已有五年时间。2024 年 10 月是 Python 3.8 版本发布的最后一个月&#xff0c;从 2024 年 10 月开始&#xff0c;如果存在安全错误&#xff0c;Python 开发团队将不会修复该错误。有必要把python3.8升级python3.10。 新加apt源…

数据结构 ——— 层序遍历链式二叉树

目录 链式二叉树示意图​编辑 何为层序遍历 手搓一个链式二叉树 实现层序遍历链式二叉树 链式二叉树示意图 何为层序遍历 和前中后序遍历不同&#xff0c;前中后序遍历链式二叉树需要利用递归才能遍历 而层序遍历是非递归的形式&#xff0c;如上图&#xff1a;层序遍历的…

DevOps工程技术价值流:加速业务价值流的落地实践与深度赋能

DevOps的兴起&#xff0c;得益于敏捷软件开发的普及与IT基础设施代码化管理的革新。敏捷宣言虽已解决了研发流程中的诸多挑战&#xff0c;但代码开发仅是漫长价值链的一环&#xff0c;开发前后的诸多问题仍亟待解决。与此同时&#xff0c;虚拟化和云计算技术的飞跃&#xff0c;…

python json详解

json 是 Python 中用于处理 JSON 数据的标准库。JSON&#xff08;JavaScript Object Notation&#xff09;是一种轻量级的数据交换格式&#xff0c;易于人类阅读和编写&#xff0c;同时也易于机器解析和生成。Python 的 json 模块提供了将 Python 对象与 JSON 数据相互转换的功…

WPS宏编辑器开发,单元格内容变更自动触发事件

WPS中Excel的“触发器” 写在前面宏的开发1、切换宏编辑器开发环境2、小练习&#xff1a;自定义函数3、完成功能需求&#xff1a;单元格内容变更自动触发事件 总结 写在前面 我先生用EXCEL做了一张学生存款表。设计得很简单&#xff0c;A学生已存款X元&#xff0c;A学生再次存…

新版Apache Tomcat ⽬目录文件讲解(笔记)

简介&#xff1a;Tomcat⽬目录⽂文件讲解 bin &#xff08;关注&#xff09; 启动和关闭tomcat脚本 startup.sh/startup.bat (Linux平台或Mac上的启动脚本/Windows平台上的启动脚本) shutdown.sh/shutdown.bat (Linux平台或Mac上的关闭脚本/Windows平台上的关闭脚本) conf&am…

Go 语言已立足主流,编程语言排行榜24 年 11 月

Go语言概述 Go语言&#xff0c;简称Golang&#xff0c;是由Google的Robert Griesemer、Rob Pike和Ken Thompson在2007年设计&#xff0c;并于2009年11月正式宣布推出的静态类型、编译型开源编程语言。Go语言以其提高编程效率、软件构建速度和运行时性能的设计目标&#xff0c;…

Kettle配置数据源错误“Driver class ‘org.gjt.mm.mysql.Driver‘ could not be found”解决记录

问题描述 错误提示&#xff1a;“Driver class ‘org.gjt.mm.mysql.Driver’ could not be found, make sure the ‘MySQL’ driver (jar file) is installed.” 原因分析&#xff1a; 根据错误提示是缺少了相关的数据源连接jar包。 解决方案&#xff1a; 安装对应的Mysql…

PCA 原理推导

针对高维数据的降维问题&#xff0c;PCA 的基本思路如下&#xff1a;首先将需要降维的数据的各个变量标准化&#xff08;规范化&#xff09;为均值为 0&#xff0c;方差为 1 的数据集&#xff0c;然后对标准化后的数据进行正交变换&#xff0c;将原来的数据转换为若干个线性无关…

河道无人机雷达测流监测系统由哪几部分组成?

在现代水利管理中&#xff0c;河道无人机雷达监测系统正逐渐成为一种重要的工具&#xff0c;为河道的安全和管理提供了强大的技术支持。那么&#xff0c;这个先进的监测系统究竟由哪几部分组成呢&#xff1f; 河道无人机雷达监测系统工作原理 雷达传感器通过发射电磁波或激光束…

DDRPHY数字IC后端设计实现系列专题之数字后端floorplanpowerplan设计

3.2.3 特殊单元的布局 布图阶段除了布置 I/O 单元和宏单元&#xff0c;在 28nm 制程工艺时&#xff0c;还需要处理两种特 殊的物理单元&#xff0c;Endcap 和 Tapcell。 DDRPHY数字IC后端设计实现系列专题之后端设计导入&#xff0c;IO Ring设计 &#xff08;1&#xff09;拐…

实现金蝶云与MySQL的无缝数据集成

金蝶云与MySQL的费用申请单数据集成案例 金蝶云星空数据集成到MySQL的技术案例分享 在企业信息化系统中&#xff0c;数据的高效流转和准确对接是业务顺利运行的关键。本文将聚焦于一个具体的系统对接集成案例&#xff1a;如何通过轻易云数据集成平台&#xff0c;将金蝶云星空中…

Flink Source 详解

Flink Source 详解 原文 flip-27 FLIP-27 介绍了新版本Source 接口定义及架构 相比于SourceFunction&#xff0c;新版本的Source更具灵活性&#xff0c;原因是将“splits数据获取”与真“正数据获取”逻辑进行了分离 重要部件 Source 作为工厂类&#xff0c;会创建以下两…

Android Settings 单元测试 | 如何运行单元测试?

背景 在Android Settings 单元测试 | Telephony Network 模块 APN 案例中粗略介绍了单元测试逻辑内容&#xff0c;但是在独立APK里面如何将单元测试跑起来还是有疑问&#xff0c;因为APP不能直接install&#xff0c;无法借助Android Studio直接Run&#xff0c;在安装的一步会报…

【Qt聊天室】客户端实现总结

目录 1. 项目概述 2. 功能实现 2.1 主窗口设计 2.2 功能性窗口 2.3 主界面功能实现 2.4 聊天界面功能实现 2.5 个人信息功能开发 2.6 用户信息界面设置功能 2.7 单聊与群聊 2.8 登录窗口 2.9 消息功能 3. 核心设计逻辑 3.1 核心类 3.2 前后端交互与DataCenter 4…

java瑞吉外卖

环境搭建 一、数据库环境搭建 1.新建数据库reggie&#xff0c;这里字符集一般用utf8mb4&#xff0c;排序规则一般用utf8mb4_general_ci或utf8mb4_unicode_ci 2.然后导入表结构 二、创建springboot工程 然后检查maven仓库设置&#xff0c;jdk 这是我的pom.xml文件 <?xml …

App Store用户评论如何影响ASO优化

您是否专注于提高应用的知名度&#xff0c;并想知道应用商店评分和用户评论如何发挥作用&#xff1f;应用商店用户评论和评分对于塑造应用的成功至关重要&#xff0c;并且可以显著影响您的应用商店优化 (ASO) 策略。本文提供了利用这些元素为您带来优势的见解和策略。 如今&…