0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

拒绝“爆雷”!GaussDB(for MySQL) 新上线了这个功能

jf_94205927 来源:jf_94205927 作者:jf_94205927 2023-06-30 09:51 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

摘要:智能把控大数据量查询,防患系统奔溃于未然

什么是最大读取行

一直以来,大数据量查询是数据库 DBA 们调优的重点,DBA 们通常十八般武艺轮番上阵以期提升大数据查询的性能:例如分库分表、给表增加索引、设定合理的 WHERE 查询条件、限定单次查询的条数……

然而,DBA 再厉害,应用程序千千万,写代码的程序员万码奔腾,大数据量的查询像地雷,不定什么时候就爆了。比如隐藏在某段代码里的查询,因为一个新手程序员的经验不足,查询代码写得欠佳,没有 WHERE 子句或缺少索引引发了不必要的多行读取,甚至全表扫描,给服务器带来了过度的压力,导致业务执行缓慢,甚至最后服务器 OOM 崩溃。

为了避免这种“爆雷”,GaussDB(for MySQL)近期上线了最大读取行特性。优化器产生执行计划后,如果优化器预估的读取行数超过了所设置的最大读取行阈值,则自动中止查询,将雷的导火索切断。

这种机制的优点在于:执行计划阶段就对查询进行了干预,而不是语句开始执行后在执行过程中进行中断。既杜绝了劣质查询对服务器和业务运行造成的风险,又大大节省了时间和资源。

如何设置最大读取行

在 GaussDB(for MySQL)中,设置 rds_max_row_read,指定查询允许读取的最大行数。GaussDB(for MySQL)收到查询指令,执行查询之前,会对查询要读取的行数进行估计。当估值超过所设置的最大读取行时,将中止查询,即查询没有机会运行,提前规避不必要的资源消耗。

下面是一份测试数据,说明了开启最大读取行前后的差异。

假设表 t1 有 4M 大小的行,当开发人员或应用程序尝试运行以下查询时,运行需要 7 分钟。

mysql> SELECT * FROM t1;

WHERE 子句的缺失致使需要全表扫描,查询耗时长。对于更大的表,这类查询将需要更多的耗时,使服务器消耗更多资源,查询耗时甚至可能高达数小时。

最大读取行特性的使用,可以节省宝贵的时间和资源。比如假设将最大读取行数指定为 1000000:

mysql> set rds_max_row_read =1000000;

Query OK, 0 rows affected (0.00 sec)

修改后,重新运行不含 WHERE 子句的查询,收到了读取行超限的提示,查询被停止。

mysql> SELECT * FROM t1;

ERROR HY000: Expected number of read rows exceeds the maximum allowed (see @@rds_max_row_read)

通过最大读取行,相当于拥有了一个工具,DBA 或者软件工程师根据业务情况可以自如设置和调整限制规则,保证业务正常运行的同时,限制次优查询,避免性能异常。

适用范围

适用于 SELECT、CREATE SELECT 和 INSERT SELECT。

功能开启

默认情况下,该功能是禁用的,只有当 rds_max_row_read 设置了值时,该功能才会被激活。

为了功能的稳定,避免无心的错误设置对业务造成不必要的影响,rds_max_row_read 做了最低值限制,不允许用户设置比最低值更低的值。

实现原理

wKgaomSeNQ2AcdSfAAEnhwCko5k152.png

GaussDB(for MySQL)通过遍历每个查询块并聚合各查询块的贡献来整体评估查询的读取行数:也就是对各 join 对象的读取行数评估后累加。

如果在累加评估过程中的某一刻,估计值超过了所设置的限制,查询将被终止。

对于关联子查询,评估办法为:评估子查询的读取行数,然后乘以查询被执行的次数。

需要特别说明的是,对每个 JOIN 对象的估计是执行计划预估返回的行数,可能与真实执行返回的行数有偏差。这虽然是一个相对简单的评估模型,但是我们坚信其具有足够的鲁棒性。

对于复杂查询,GaussDB(for MySQL)还通过 optimizer trace 提供了更多信息以帮助您确定优化器做决策的原因及如何优化查询。

示例

示例 1

mysql> EXPLAIN format=tree SELECT * FROM table_1, table_2;

+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------+

| EXPLAIN |

+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------+

| -> Inner hash join (no condition) (cost=6.50 rows=54)

-> Table scan on table_1 (cost=0.19 rows=9)

-> Hash

-> Table scan on table_2 (cost=0.85 rows=6)

|

+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------+

1 row in set (0.00 sec)

mysql> SET rds_max_row_read =20;

Query OK, 0 rows affected (0.00 sec)

mysql> SELECT * FROM table_1, table_2;

ERROR 1888 (HY000): The expected number of read rows exceeds the allowed maximum (see @@rds_max_row_read)

查询读取的行太多,我们尝试在 optimizer trace 的帮助下寻找原因:

SET optimizer_trace="enabled=on";

SELECT * from table_1, table_2;

SELECT * FROM INFORMATION_SCHEMA.OPTIMIZER_TRACE;

在 optimizer trace 中,可以找到:

{

"Max_row_read": {

"select#": 1,

"current_estimate_of_rows": 54,

"rows_contributed_by_this_query_block": 54

}

}

这表示此查询中的唯一查询块,行读取数为 54。

执行计划中的这个评估有多准确呢?

执行如下查询查看语句实际被执行的次数:

mysql> show status like "handler_read_rnd_next";

+----------------------------+-------+

| Variable_name | Value |

+----------------------------+-------+

| Handler_read_rnd_next | 17 |

+----------------------------+-------+

1 rows in set (0.00 sec)

handler_read_rnd_next 显示实际上的读取是 17 行,而不是 54 行。

这个 17 是怎么来的呢?

这是一个哈希连接:

-遍历整张表时,左表有 9 行数据+1 行额外行。

-右表有 6 行+1 行额外行。

优化器中会预估返回读取行,例如,54。在这个示例中,它并没有很好地猜测到返回的行数,它高估了行读取的数量。在大多数情况下,读取行数的估计不够精确,但可以肯定的是,它是足够稳健的,能达到相应的目的。

示例 2

创建例表 t1:

mysql> CREATE TABLE t1(a INT);

在表中填充 1536 行数据后。将 rds_max_row_read 设置为 500,进行以下测试查询:

mysql> SELECT * FROM t1 WHERE a>6;

ERROR HY000: Expected number of read rows exceeds the maximum allowed (see @@rds_max_row_read)

在 optimizer trac 的帮助下,可以看到优化器估计的读取行数是 512 行,因此查询被终止。如果在 a 字段上添加索引(这是一件明智的事情),同一查询的估计读取行数是 1,查询检测顺利通过。

这个简单的示例说明:最大读取行能帮助您编写更加优质的查询语句。

结论

最大读取行特性针对读取过多行的查询,识别和过滤出效率低下的查询。用户可以为读取行数设置阈值,超过该阈值则终止查询。为了识别此类查询,GaussDB(for MySQL)在优化器中进行了读取总行数的粗略估计。当查询终止时,可以检查 optimizer trace,从中收集线索,以帮助重写更高效的查询。

简而言之,最大读取行为用户提供了一个工具,使他们可以更充分地利用手上的资源。

审核编辑 黄宇

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 华为云
    +关注

    关注

    3

    文章

    2837

    浏览量

    19403
收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    英诺达ECDC上线RDC跨复位域检查新功能

    英诺达自主研发的静态验证系列产品EnAltius昂屹CDC(ECDC),近日正式上线跨复位域(Reset Domain Crossing, RDC)检查新功能,其静态验证EDA工具链得以进一步完善,为芯片设计团队提供更严谨、更
    的头像 发表于 04-21 09:34 325次阅读

    从业务库到实时分析库,NineData 构建 MySQL到SelectDB 同步链路

    MySQL 到 SelectDB,难点从来不是“把数据搬过去”,而是把这件事做成一条真正可靠的生产链路。 NineData 在这个场景里的价值,不只是提供一条复制通道,而是把任务创建、实时复制
    的头像 发表于 03-31 12:54 598次阅读
    从业务库到实时分析库,NineData 构建 <b class='flag-5'>MySQL</b>到SelectDB 同步链路

    恒讯科技解析:如何安装MySQL并创建数据库

    安装和管理MySQL不必复杂。只需几分钟,你就能在Linux服务器上搭建MySQL,创建第一个数据库,甚至自动化备份——同时确保数据安全有序。 什么是 MySQL  MySQL 是一个
    的头像 发表于 01-14 14:25 487次阅读

    工业数据中台支持接入MySQL数据库吗

    工业数据中台完全支持接入MySQL数据库 ,且通过数据同步、集成与治理等技术手段,能够充分发挥MySQL在数据存储与事务处理方面的优势,同时弥补其在数据分析与共享能力上的不足,具体分析如下: 技术
    的头像 发表于 12-04 11:23 579次阅读
    工业数据中台支持接入<b class='flag-5'>MySQL</b>数据库吗

    一颗芯片卖是什么感觉

    转载自《钟林谈芯》 一颗芯片卖是什么感觉?是痛并快乐着。 市场的火热,出乎意料。交付的压力使人焦虑和心痛,不愿辜负客户、市场对三伍微的认可和支持。尽管之前做了“足够”的安全备货,但市场需求的
    的头像 发表于 11-26 15:11 604次阅读
    一颗芯片卖<b class='flag-5'>爆</b><b class='flag-5'>了</b>是什么感觉

    不止于4层!华秋PCB 6层板款重磅上线

    4层之后,再看6层上月,华秋PCB推出了4层板款,以“真香”价格引爆市场。今天,华秋PCB怀着更大的诚意,为您带来承诺中的下一站——「华秋PCB6层板款」正式登场!不止于降价,我们重新定义6层板
    的头像 发表于 11-12 07:33 761次阅读
    不止于4层!华秋PCB 6层板<b class='flag-5'>爆</b>款重磅<b class='flag-5'>上线</b>

    iPhone 17!今年下半年看什么新技术、新趋势?

    iPhone 17!今年下半年看什么新技术、新趋势?
    的头像 发表于 09-23 10:48 888次阅读
    iPhone 17<b class='flag-5'>爆</b><b class='flag-5'>了</b>!今年下半年看什么新技术、新趋势?

    科技云报到:坏了!数字人真要改百业

    科技云报到:坏了!数字人真要改百业
    的头像 发表于 08-14 14:41 718次阅读

    CentOS 7下MySQL 8双主热备高可用架构全解

    Centos7部署MySQL8+keepalived双主热备(含Keepalived配置与GTID同步优化方案) 架构拓扑原理 GTID同步 VIP 192.168.1.100 MySQL主节点1
    的头像 发表于 08-12 17:08 1075次阅读

    MySQL配置调优技巧

    上个月,我们公司的核心业务系统突然出现大面积超时,用户投诉电话不断。经过紧急排查,发现是MySQL服务器CPU飙升到99%,大量慢查询堆积。通过一系列配置调优和SQL优化,最终在30分钟内恢复服务。
    的头像 发表于 07-31 10:27 892次阅读

    MySQL 8.0性能优化实战指南

    作为一名运维工程师,MySQL数据库优化是我们日常工作中最具挑战性的任务之一。MySQL 8.0作为当前主流版本,在性能、安全性和功能上都有显著提升,但如何充分发挥其潜力,仍需要我们
    的头像 发表于 07-24 11:48 1246次阅读

    MySQL的组成结构与结构化查询语言详解

    MySQL作为世界上最流行的开源关系型数据库管理系统,采用了分层架构设计
    的头像 发表于 07-14 11:21 858次阅读

    MySQL数据备份与恢复策略

    数据是企业的核心资产,MySQL作为主流的关系型数据库管理系统,其数据的安全性和可靠性至关重要。本文将深入探讨MySQL的数据备份策略、常用备份工具以及数据恢复的最佳实践,帮助运维工程师构建完善的数据保护体系。
    的头像 发表于 07-14 11:11 986次阅读

    企业级MySQL数据库管理指南

    在当今数字化时代,MySQL作为全球最受欢迎的开源关系型数据库,承载着企业核心业务数据的存储与处理。作为数据库管理员(DBA),掌握MySQL的企业级部署、优化、维护技能至关重要。本文将从实战角度出发,系统阐述MySQL在企业环
    的头像 发表于 07-09 09:50 1003次阅读

    远程访问内网MySQL数据库?这个方案更简单

    各位开发者朋友们,是否还在为无法随时随地访问内网MySQL数据库而烦恼?今天分享一个超实用的方法,通过容器部署 MySQL 结合 ZeroNews 内网穿透,让你在任何地方都能安全访问和管理数据库
    的头像 发表于 07-04 18:06 1105次阅读
    远程访问内网<b class='flag-5'>MySQL</b>数据库?<b class='flag-5'>这个</b>方案更简单