数据库性能问题总结--屡次发生的Oracle谓词越界
点击上方"蓝字"
关注我们,享更多干货!
近期在客户现场屡次遇到由于统计信息过旧,导致执行计划选错引发的数据库性能问题,今天做个总结。
谓词越界常见发生在 where 谓词是时间字段的情况,总的来说统计信息记录的是一个过旧的时间,而 SQL 传入的时间是一个最新的时间范围(往往是 <time time1<c<time2)。由于统计信息不全,按照 CBO 计算出来的结果集就很小,在多表关联的情况下,CBO 就会选择认为的最优的关联方式,而实际执行时发现不是那么回事,有大量结果集需要扫描,就会爆发 SQL 性能问题。
谓词越界就是 select 的谓词的条件不在统计信息 low_value 和 high_value 之间,在实际选择结果集要大于 CBO 记录的结果集数量,即实际的 selectivity 偏大,这种情况下 CBO 评估出来的 selectivity 会出现严重的偏差,导致 CBO 选错执行计划。
测试验证
下面做一组测试,从执行计划 cost 看谓词越界的发生过程,先插入部分数据:
DECLARE
i INT;
BEGIN
i := 78179;
WHILE(i < 100000)
LOOP
i := i + 1;
INSERT INTO test_obj(object_id) VALUES(i);
COMMIT;
END LOOP;
END;
/
查看此时的 num_rows:
TEST@PROD1> select count(*) from test_obj;COUNT(*)
----------94283
TEST@PROD1> select max(object_ID),dump(max(object_id),16) from test_obj;MAX(OBJECT_ID) DUMP(MAX(OBJECT_ID),16)
-------------- ----------------------------------------100000 Typ=2 Len=2: c3,b
TEST@PROD1> select min(object_ID),dump(min(object_id),16) from test_obj;MIN(OBJECT_ID ) DUMP(MIN(OBJECT_ID),16)
------------------------------ ----------------------------------------2 Typ=2 Len=2: c1,3 --C103
不收集统计信息,此时统计列统计信息过旧,HIGH_VALUE 依然是原来的值 78179。
TEST@PROD1> select low_value ,high_value,num_distinct,num_nulls from DBA_TAB_COL_STATISTICS where table_name='TEST_OBJ' and owner='TEST';Distinct Number
LOW_VALUE HIGH_VALUE Values Nulls
------------------------------ ------------------------------ ------------ ----------
C103 C3085250 72,462(原值) 0
查询结果返回 2081 行结果集。
TEST@PROD1> select count(*) from test_obj where object_id between 78200 and 81000;COUNT(*)
----------2801
计算公式为:
selectivity=((VAL2 - VAL1) / (HIGH_VALUE - LOW_VALUE)+2 / NUM_DISTINCT) * null_adjust
null_adjust=(NUM_ROES - NUM_NULLS) / NUM_ROES计算结果为:
TEST@PROD1> select round(((81000-78200)/(100000-2)+2/94283)*(94283-0)/94283*94283) from dual; ROUND(((81000-78200)/(100000-2)+2/94283)*(94283-0)/94283*94283)
---------------------------------------------------------------2642
查看结果集发现 dictionary 值为 1,这明显是一个错误的执行计划,由于统计信息过旧,已经低于谓词条件区间(谓词过界)导致 CBO 低估了查询成本。
TEST@PROD1> select count(*) from test_obj where object_id between 78200 and 81000;Execution Plan
----------------------------------------------------------
Plan hash value: 2217143630-------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 5 | 289 (1)| 00:00:04 |
| 1 | SORT AGGREGATE | | 1 | 5 | | |
|* 2 | TABLE ACCESS FULL| TEST_OBJ | 1 | 5 | 289 (1)| 00:00:04 |
-------------------------------------------------------------------------------Predicate Information (identified by operation id):
---------------------------------------------------2 - filter("OBJECT_ID">=78200 AND "OBJECT_ID"<=81000)Statistics
----------------------------------------------------------1 recursive calls0 db block gets1117 consistent gets0 physical reads0 redo size423 bytes sent via SQL*Net to client419 bytes received via SQL*Net from client2 SQL*Net roundtrips to/from client0 sorts (memory)0 sorts (disk)1 rows processed
重新收集统计信息再次查看执行计划。
TEST@PROD1> exec dbms_stats.gather_table_stats('test','test_obj');
TEST@PROD1> select low_value ,high_value,num_distinct,num_nulls from DBA_TAB_COL_STATISTICS where table_name='TEST_OBJ' and owner='TEST';Distinct Number
LOW_VALUE HIGH_VALUE Values Nulls
-------------------- -------------------- ------------ ----------
C103 C30B 94,283 0
此时统计信息 HIGH_VALUE 已经和最初计算的值相等,Typ=2 Len=2: c3,b。再次查看执行计划,此时 CBO 已经能够产生了正确的执行计划了。
执行计划为:
TEST@PROD1> select count(*) from test_obj where object_id between 78200 and 81000;Execution Plan
----------------------------------------------------------
Plan hash value: 2217143630-------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 5 | 314 (1)| 00:00:04 |
| 1 | SORT AGGREGATE | | 1 | 5 | | |
|* 2 | TABLE ACCESS FULL| TEST_OBJ | 2642 | 13210 | 314 (1)| 00:00:04 |
-------------------------------------------------------------------------------Predicate Information (identified by operation id):
---------------------------------------------------2 - filter("OBJECT_ID">=78200 AND "OBJECT_ID"<=81000)Statistics
----------------------------------------------------------0 recursive calls0 db block gets1117 consistent gets0 physical reads0 redo size423 bytes sent via SQL*Net to client419 bytes received via SQL*Net from client2 SQL*Net roundtrips to/from client0 sorts (memory)0 sorts (disk)1 rows processed
谓词越界主要发生在大表,按照 Oracle 统计信息收集机制,表的数据变化量达到 10% 以上才会进行统计信息收集,大表不常收集统计信息就容易爆发谓词越界。
预防方式
可对关键表实行按谓词查询条件分区,即按天或者按月分区可规避此问题发生。
关于作者
任艳杰,云和恩墨Oracle技术顾问,长期致力于大型Oracle数据库维护工作,具备扎实的理论基础和丰富的实践经验,擅长数据恢复、性能优化、数据迁移等。
墨天轮原文链接:https://www.modb.pro/db/44787(复制到浏览器或者点击“阅读原文”立即查看)
END
长按二维码 热招职位一键投递
长按二维码 热招职位一键投递
MySQL/PG/Oracle DBA
数据库专家(售前)、销售总监/经理
200+热招职位 覆盖全国40+所城市
由ACDU(中国DBA联盟)和墨天轮联合出品的全新视频节目「数据三分钟」已发布多期,快速了解数据行业动态,快关注我们的视频号看看吧!↓↓↓
点击下图查看更多 ↓
云和恩墨大讲堂 | 一个分享交流的地方
长按,识别二维码,加入万人交流社群
请备注:云和恩墨大讲堂
点个“在看”
你的喜欢会被看到❤
数据库性能问题总结--屡次发生的Oracle谓词越界相关推荐
- 屡次发生的Oracle谓词越界
近期在客户现场屡次遇到由于统计信息过旧导致执行计划选错引发的数据库性能问题,今天做个总结: 谓词越界常见发生在where谓词是时间字段的,总的来说统计信息记录的是一个过旧的时间,而SQL传入的时间是一 ...
- loadrunner录制事件为0_Oracle数据库性能监控|LoadRunner 中配置监控Oracle
Oracle 是目前世界上大型应用系统广泛使用的数据库,Oracle 数据库产品为财富排行榜上的前1000 家公司所采用,许多大型网站也选用了Oracle 系统.Oracle 内部结构比较复杂,如图8 ...
- Oracle统计信息不准(谓词越界)造成的性能问题
什么是谓词越界?谓词越界其实就是SQL语句的查询条件超出了数据库统计信息所记录的范围.谓词越界会导致Oracle优化器错误的选择SQL语句的执行计划,导致性能问题. 这里举一个简单的例子说明谓词越界导 ...
- sql server数据库性能的优化
编者按:数据库性能优化和数据库管理系统密切相关,不同的数据库管理系统在具体操作上有很大不同.继本报连续在2003年第48期.49期上刊登<sybase数据库性能调优>和<oracle ...
- openGauss数据库性能调优概述及实例分析
目录 调优思路概述 调优流程 确定性能调优范围 性能因素 调优范围确定 硬件瓶颈点分析 CPU 内存 I/O 网络 查询最耗性能的SQL 分析作业是否被阻塞 调优思路概述 openGauss的总体性能 ...
- oracle数据库性能awr,常见问题:如何使用AWR报告来诊断数据库性能问题
常见问题:如何使用AWR报告来诊断数据库性能问题 (Doc ID 1523048.1) Last updated on FEBRUARY 03, 2019 适用于: Oracle Database - ...
- Oracle优化01-引起数据库性能问题的因素
思维导图 概述 一个数据库是否存在性能问题,基本上在系统设计的时候就决定了,这个系统设计包括软件的设计.数据库的设计和硬件的设计.其中更细节的分类参考目录. 在一个系统的设计阶段,其中任何一个环节存在 ...
- oracle使用 union all 用自增序列_值得收藏的Oracle数据库性能优化
值得收藏的Oracle数据库性能优化 年尾了,新的一波面试军又要开始了,被问到最多的可能就是性能优化,尤其是数据库性能优化,这个面试题不管是初中高级工程师都会被问到.因此我觉得下面31点ORACLE优 ...
- REDO LOG大小引起的Oracle数据库性能下降
今天做一个7W条记录/s插入oracle数据库的实验.两台服务器都在本地复制一个1280W条记录的表到另外一个相同结构的表里面,一台服务器花了12s另一台却花了近2min.在em中生成插入时的awr报 ...
最新文章
- Matlab数据的可视化 -- 茎干图
- ClickHouse系列教程七:centos下源码编译安装及报错解决
- IntelliJ IDEA安装主题详细步骤
- 面试题-两个数值交换
- [转]浅谈OCR之Tesseract
- JDK8新特性之接口默认方法与静态方法
- HighNewTech:LL / GCP BOOTH at CES 2019 - January 8-11, 2019 - Westgate Convention Center Las Vegas
- python 关于异常处理 try...except... 的两个案例
- u盘安装linux启动报错,U盘安装centos7,启动报错
- php 多表查询输出,ThinkPHP多表查询
- 【 Grey Hack 】WIFI万能钥匙
- [NOIP2010提高组]关押罪犯
- Docker精华问答:Docker与虚拟机的区别?| 技术头条
- 止欲知足,为获得幸福生活的根本法则之一
- fpga烧写bin文件_Altera FPGA烧写步骤及注意事项_骏龙科技
- oracle10g rac导出ocr,Oracle RAC 迁移OCR(10g)
- 非科班研究生转码-零基础学java笔记总结复习(1)
- SQL 删除数据空格(Trim、RTrim、LTrim函数)
- 海伦公式已知三边求面积
- linuxprobe