聊聊Oracle自适应查询优化

news2025/3/1 6:52:23

成也AQO败也AQO

因为工作的原因,我们接触到的客户大部分是金融和运营商行业,这些客户有个最大的特点是追求稳定,对于使用数据库新特性持保守的态度,不会轻易尝试某些可能会导致生产系统不稳定的新特性。上线前通常都会将一些新特性禁用,避免上线后可能会由于这些新特性而导致性能出现抖动。

但是近期遇到的一个case,却颠覆了我对这些新特性的看法。

最近我们在帮客户分析一条SQL的性能问题,过程中发现由于数据库的Adaptive Plan参数是默认的开启状态,产生了比较多的子游标,当使用某个条件时就会出现性能下降的情况。作为本能的反应,我们建议客户关闭Adaptive Plan功能,给出的理由是“虽然未必是最优的,却是我们能接受的稳定性能”。修改完参数客户重新测试执行了相关的业务模块,之前有问题的SQL按照预期很顺利的执行完成,但是又出现了新的情况,有另一条在之前的测试中秒级执行的SQL这次却整整用了2000+秒才执行完成。这不由得让我们重新审视Adaptive Plan带给数据库的正面影响。

什么是 AQO (自适应查询优化)

为了SQL语句能够始终以最优的执行计划执行,Oracle在不断的探索和革新。从9i的绑定变量Peeking,到11g的ACS和Statistics Feedback,在12c中则引入了Adaptive Query Optimization。

Statistics Feedback在SQL第一次执行时,根据统计信息生成的执行计划执行SQL,执行过程中执行计划不能改变,如果统计信息不准确,在SQL第一次执行时可能就会引起灾难性的问题。而且,Statistics Feedback生成的数据只能保存在内存中而不能固化下来,如果过程中数据库发生了重启,需要重新收集Statistics Feedback信息,这可能导致再一次的灾难发生。

Adaptive Query Optimization就是为了彻底解决这两个问题而引入的,具体包括两方面的功能:自适应执行计划和自适应统计信息。
在这里插入图片描述

自适应计划 (Adaptive Plans)

区别于Statistics Feedback在第一次执行后对比实际运行数据和统计信息对比,发现差异较大再对执行计划进行干预的方式不同,Adaptive Plans将执行计划决策和统计信息收集结合起来,在运行时检测基数估计值是否与执行计划中操作所看到的实际行数有很大的差异,如果差异较大,将会对执行计划进行自动调整,避免SQL语句选择次优的执行计划影响执行性能。具体的干预方式有Join Method、Parallel Distribution Methods和Bitmap Pruning 3种。

Join Method

主要是在Nest Loop和Hash Join之间进行评估决策。执行计划根据收集到的统计信息,计算不同执行计划优劣的“临界点”。比如当A表扫描的行数少于10时Nest Loop是最优的,当扫描的行数大于10则Hash Join是最优的,那么10就是这两种连接方式的“临界点”。有了这个值之后,优化器配置Buffer统计收集器缓存数据,如果扫描涉及到的行数超过10则使用Hash Join,反之则使用Nest Loop。

PARALLEL DISTRIBUTION METHODS

当SQL语句并行执行时,某些操作(如排序、聚合和连接)需要在执行该语句的并行服务器进程之间重新分配数据。优化器选择的分发方法取决于操作、所涉及的并行服务器进程的数量以及预期的行数。如果优化器不准确地估计行数,那么所选择的分布方法可能不是最优的,并可能导致一些并行服务器进程未得到充分利用。

和Join Method的决策方式类似,使用新的自适应分布式方法HYBRID HASH,优化器可以将其分布式方法决策推迟到执行时。相关的并行操作之前会收集统计信息,如果实际涉及的行数少于阈值,则将分布式方法从Hash切换到Broadcast;如果涉及的行数达到阈值,则使用Hash方法。

自适应统计信息

通过上述的介绍,相信大家已经理解了Adaptive Plans是如何指导优化器生成最优执行计划的,在这其中统计信息发挥了非常重要的作用。接下来我们再来看看AQP中自适应统计信息又是如何工作的。

自适应统计信息包括Dynamic Statistics、Automatic Re-optimization和SQL Plan Directives三部分内容。

Dynamic Statistics

在12c之前称为Dynamic Sampling,进化后的动态统计信息引入了Level 11,允许优化器在所有表已经存在统计信息的情况下,自动选择是否使用动态统计信息。动态统计信息收集的数据不仅仅针对单表访问,还包括Join和Group-By谓词条件的统计信息,以此来获得更准确的基数评估。

Automatic Re-optimization

主要包括两部分内容,Statistics Feedback和Performance Feedback。

Statistics Feedback就是11g中的Cardinality Feedback,前面我们也多次提到过其相关的功能,这里就不再赘述。

Performance Feedback主要用于提高Automatic Degree of Parallelism模式下,重复执行的SQL语句选择的并行度。

SQL Plan Directives

前面讲到Statistics Feedback不能保存评估出的信息,因此Oracle又引入了SQL plan directives功能。SQL plan directives 可以看成是持久化的动态采样信息,当优化器发现有评估错误的数据时,会自动生成SPD,这些数据首先保存在SGA内存中,每隔15分钟由后台进程写出到数据字典表中。和SQL Profile和SPM等SQL执行计划稳定工具不同的是,SPD关联的是表或者列等特定对象,而不是某条特定SQL语句。

SPD包括DYNAMIC_SAMPLING 和DYNAMIC_SAMPLING_RESULT两种类型,其中DYNAMIC_SAMPLING用于指示优化器当看到谓词过滤涉及多个列的查询时,使用dynamic sampling来解决基数评估不准确的问题;而DYNAMIC_SAMPLING_RESULT则替代了12.1中的Result Cache,将动态抽样的结果保存在SQL directive仓库中。

写在最后

总体来看,Adaptive Query Optimization涉及到非常多的组件,这也让整个实现流程变得非常复杂,以至于即使笔者这样的老DBA也花了不少时间梳理各个组件之间的关系和理解工作原理,从而更好的用于指导生产实施。

理想美好而现实却是骨感的,AQP的设计理念非常完美但在实际生产过程中仍然存在不少的问题。

统计信息收集非常频繁,生产环境中的各种组合查询千差万别,使得动态统计信息收集介入非常频繁,极端的情况下,9万条SQL可能有7万条是系统自发采集统计信息的,这也让生产系统无形中承载了更多的负担;

过多的SPD会让系统变的更敏感。不同的绑定变量代入值会生成不同的游标,让同一条SQL的执行计划切换非常频繁,而这种切换并不能保证每次都是在最优路线上。对于稳定压倒一切的大多数客户来说,宁愿稳定的跑在次优路线上,也不愿意承担哪怕万分之一的不稳定带来的风险。

或者正因为存在着种种的问题,12.2进行了较大的调整,optimizer_adaptive_features参数被废弃,引入了两个新的参数optimizer_adaptive_plans 和optimizer_adaptive_statistics。其中,optimizer_adaptive_plans用于控制是否允许创建Adaptive Plan,该参数默认为TRUE;optimizer_adaptive_statistics 则用于控制是否允许优化器使用 Adaptive Statistics,该参数默认为FALSE,从而使得优化器不会在解析时间修改SQL语句的执行计划。这也是关注到大多数客户优先考虑的是系统稳定性而不是最大化查询执行性能,最终权衡的一个结果。

最后,我们也看到了积极的一面,在关闭了AQP功能之后,才发现不知不觉中SPD也帮我们规避了不少的风险,默默的让数据库运行的更加高效。只是从理想到现实,仍然有很长的路要走,这也是Oracle不断前进的方向和动力,相信在后续的版本中会有更大的进步!

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

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

相关文章

【数据库】选择题+填空+简答

1.关于冗余数据的叙述中,不正确的是() A.冗余的存在容易破坏数据库的完整新 B.冗余的存在给数据库的维护增加困难 C.不应该在数据库中存储任何冗余数据 D.冗余数据是指由基本数据导出的数据 C 2.最终用户使用的数据视图称为(&…

Comparator.comparing 排序注意

1. 对数字型字符串排序 List<String> values new ArrayList<>();values.add("10");values.add("6");values.add("20");values.add("30");values.add("50");//方法1 &#xff08;正确的排序方法&#xff09;//倒…

R语言的数据结构-矩阵

【图书推荐】《R语言医学数据分析实践》-CSDN博客 《R语言医学数据分析实践 李丹 宋立桓 蔡伟祺 清华大学出版社9787302673484》【摘要 书评 试读】- 京东图书 (jd.com) R语言医学数据分析实践-R语言的数据结构-CSDN博客 矩阵是一个二维数组&#xff0c;矩阵中的元素都具有相…

动态分区存储管理

一、实验目的 目的&#xff1a;熟悉并掌握动态分区分配的各种算法&#xff0c;熟悉并掌握动态分区中分区回收的各种情况&#xff0c;并能够实现分区合并。 任务&#xff1a;用高级语言模拟实现动态分区存储管理。 二、实验内容 1、实验内容 分区分配算法至少实现首次适应算法、…

JPG 转 PDF:免费好用的在线图片转 PDF 工具

JPG 转 PDF&#xff1a;免费好用的在线图片转 PDF 工具 在日常工作和生活中&#xff0c;我们经常需要将图片转换为 PDF 格式。无论是制作电子文档、准备演示材料&#xff0c;还是整理照片集&#xff0c;将图片转换为 PDF 都是一个常见的需求。今天为大家介绍一款完全免费、无需…

10、C++继承2

本章介绍菱形继承、虚继承和类型适应。 1、菱形继承与虚继承 在多继承中&#xff0c;可能会发生多个父类共基类的问题&#xff0c;即菱形继承。 例如&#xff1a; 解决办法&#xff1a; 父类继承基类时使用虚继承&#xff0c;在继承前加virtual&#xff0c;即&#xff1a;虚…

探索Telnet:实现Windows远程登录Ubuntu的实践指南

前言 在互联网技术日新月异的今天&#xff0c;远程登录已经成为许多开发者和系统管理员日常工作中不可或缺的一部分。虽然SSH已经成为远程登录的首选协议&#xff0c;但了解并掌握Telnet这一经典协议仍然具有重要意义。本文将带您一起探索如何使用Telnet实现Windows远程登录Ub…

字符串的常见操作【C语言】

一、案例内容 字符串的常见操作主要有创建&#xff0c;输出&#xff0c;查找指定字符或查找指定位置的字符、删除指定字符或删除指定位置的字符&#xff0c;在指定位置插入指定字符等。 二、案例代码 #include <stdio.h> #include <stdlib.h> #include <stri…

axios的引入和基本使用

一、axios的引入 使用 pnpm add axios 二、使用axios 三、axios的使用方法补充 axios除了直接使用它实例上的方法&#xff0c;还可以通过配置的方式进行使用axios({})&#xff0c;传入一个对象&#xff0c;这个对象可以有如下属性&#xff1a; url&#xff08;字符串&#…

Dart 3.6 发布,workspace 和 Digit separators

workspace 之前我们就聊过 Flutter 正在切换成 Monorepo 和支持 workspaces &#xff0c;Dart 3.6 开始&#xff0c;Pub 现在正式支持 monorepo 或 workspace 中 package 之间的共享解析。 pub workspaces 功能可确保 monorepo 中的 package 共享一组一致的依赖项&#xff0c…

三、nginx实现lnmp+discuz论坛

lnmp l&#xff1a;linux操作系统 n&#xff1a;nginx前端页面 m&#xff1a;mysql数据库&#xff0c;账号密码&#xff0c;数据库等等都保存在这个数据库里面 p&#xff1a;php——nginx擅长处理的是静态页面&#xff0c;页面登录账户&#xff0c;需要请求到数据库&#…

【MFC】如何读取rtf文件并进行展示

tf是微软的一个带格式的文件&#xff0c;比word简单&#xff0c;我们可以用写字板等程序打开编辑。下面以具体实例讲解如何在自己程序中展示rtf文件。 首先使用VS2022创建一个MFC的工程。 VIEW类需要选择richview类&#xff0c;用于展示&#xff0c;如下图&#xff1a; 运行效…

AudioSegment 将音频分割为指定长度时间片段 - python 实现

DataBall 助力快速掌握数据集的信息和使用方式&#xff0c;会员享有 百种数据集&#xff0c;持续增加中。 需要更多数据资源和技术解决方案&#xff0c;知识星球&#xff1a; “DataBall - X 数据球(free)” -------------------------------------------------------------…

【新人系列】Python 入门(十六):正则表达式

✍ 个人博客&#xff1a;https://blog.csdn.net/Newin2020?typeblog &#x1f4dd; 专栏地址&#xff1a;https://blog.csdn.net/newin2020/category_12801353.html &#x1f4e3; 专栏定位&#xff1a;为 0 基础刚入门 Python 的小伙伴提供详细的讲解&#xff0c;也欢迎大佬们…

Leetcode 每日一题9.回文数

&#x1f308;&#x1f308;&#x1f308;今天给大家分享的是:回文数的解法 目录 ​编辑 问题描述 输入输出格式 示例 约束条件 进阶挑战 解决方案 问题分析 过题图片 字符串转换法 数学方法 算法解释 题目链接 结论 问题描述 给定一个整数 x&#xff0c;我们需要…

Python Turtle 实现动态时钟:十二时辰与星空流星效果

在这篇文章中&#xff0c;我将带你通过 Python 的 turtle 模块构建一个动态可视化时钟程序。这个时钟不仅具备传统的时间显示功能&#xff0c;还融合了中国古代的十二时辰与八卦符号&#xff0c;并通过动态星空、流星效果与昼夜背景切换&#xff0c;为程序增添了观赏性和文化内…

建筑电气火灾是怎么发生的?如何降低电气火灾风险?

电气火灾一直是建筑火灾的主要诱因&#xff0c;占总火灾比例的28.4%。传统的末端配电监控手段存在覆盖范围不足、反应时间滞后等问题&#xff0c;难以及时发现并应对潜在的电气安全隐患。本文提出了一种基于通讯模块、智能微断和智能终端的建筑末端配电解决方案&#xff0c;通过…

Go有限状态机实现和实战

Go有限状态机实现和实战 有限状态机 什么是状态机 有限状态机&#xff08;Finite State Machine, FSM&#xff09;是一种用于建模系统行为的计算模型&#xff0c;它包含有限数量的状态&#xff0c;并通过事件或条件实现状态之间的转换。FSM的状态数量是有限的&#xff0c;因此称…

Qt实现自定义行编辑器

引言 开发环境项目结构ui界面设计示例代码运行效果总结qt中原有的行编辑器无法满足当前的需要,所以需要自定义行编辑器。 通过上下按键切换到不同的行编辑器,在选中的行编辑器中输入数字,编辑器呈现边框,编辑后按下回车键保存之前编辑的数值,没有按下回车键直接切换上下键…

企业级日志分析系统ELK之ELK概述

ELK 概述 ELK 介绍 什么是 ELK 早期IT架构中的系统和应用的日志分散在不同的主机和文件&#xff0c;如果应用出现问题&#xff0c;开发和运维人员想排 查原因&#xff0c;就要先找到相应的主机上的日志文件再进行查找和分析&#xff0c;所以非常不方便&#xff0c;而且还涉及…