SQL调优:带函数的谓词导致CBO Cardinality计算误差
create or replace function check_date( RDATE in date) return date is begin IF rdate< to_date('2099-01-01','YYYY-MM-DD') then return rdate; ELSIF rdate >=to_date('2099-01-01','YYYY-MM-DD') then return to_date('2000-01-01');end if;end check_date;/SQL> select check_date (sysdate) from dual;CHECK_DAT --------- 06-DEC-12drop table tab1;SQL> create table tab1 tablespace users as select * from dba_objects where rownum create view vtab1 as select object_id as id , object_name as name, object_type as type , check_date(created) cdata from tab1;View created.SQL> select count(distinct cdata) from vtab1;COUNT(DISTINCTCDATA) --------------------130SQL> exec dbms_stats.gather_table_stats('','TAB1', method_opt=>'FOR ALL COLUMNS SIZE 254');PL/SQL procedure successfully completed.
因为我们指定收集了直方图所以若直接以"created"为条件查询时可以获得较好的计算基数
SQL> select count(*) from tab1 where created >= to_date('0001-10-10','YYYY-MM-DD');COUNT(*) ----------10000Execution Plan ---------------------------------------------------------- Plan hash value: 1117438016--------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | --------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | 8 | 40 (0)| 00:00:01 | | 1 | SORT AGGREGATE | | 1 | 8 | | | |* 2 | TABLE ACCESS FULL| TAB1 | 10000 | 80000 | 40 (0)| 00:00:01 | ---------------------------------------------------------------------------Predicate Information (identified by operation id): ---------------------------------------------------2 - filter("CREATED">=TO_DATE(' 0001-10-10 00:00:00', 'syyyy-mm-ddhh24:mi:ss'))Statistics ----------------------------------------------------------1 recursive calls0 db block gets133 consistent gets0 physical reads0 redo size526 bytes sent via SQL*Net to client523 bytes received via SQL*Net from client2 SQL*Net roundtrips to/from client0 sorts (memory)0 sorts (disk)1 rows processed
在以上查询中>= to_date('0001-10-10','YYYY-MM-DD'); 这样的过滤条件实际无意义,在直接使用 "created"列作为谓词的情况下,CBO可以获得很好的基数10000。
SQL> select * from TABLE(dbms_xplan.display_cursor(NULL,NULL,'ALLSTATS LAST'));PLAN_TABLE_OUTPUT -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- SQL_ID 6zy2k9dy4cv73, child number 0 ------------------------------------- select /*+ gather_plan_statistics */ count(*) from vtab1 where cdata >= to_date('0001-10-10','YYYY-MM-DD')Plan hash value: 1117438016------------------------------------------------------------------------------------- | Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers | ------------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | | 1 |00:00:00.25 | 154 | | 1 | SORT AGGREGATE | | 1 | 1 | 1 |00:00:00.25 | 154 | |* 2 | TABLE ACCESS FULL| TAB1 | 1 | 500 | 10000 |00:00:00.31 | 154 | -------------------------------------------------------------------------------------Predicate Information (identified by operation id): ---------------------------------------------------2 - filter("CHECK_DATE"("CREATED")>=TO_DATE(' 0001-10-10 00:00:00','syyyy-mm-dd hh24:mi:ss'))21 rows selected.
通过gather_plan_statistics HINT,我们得到E-Rows 即CBO评估的基数,和 A-Rows实际的基数,可以看到这里E-Rows=500, 即在谓词左边存在使用内部函数或隐身装换的情况下,CBO无法通过现有统计信息的DISTINCT、DENSITY和HISTOGRAM获得较好的Cardinality,其基数总是统计信息中表的总行数/20,如上例中的 10000/20=500。 这就会引入不少的麻烦,因为开发人员有时候为了方便会在视图字段中嵌入自定义的函数,之后若在查询中使用该字段作为谓词条件,则可能导致CBO为相应表计算的基数偏少,是本身应当成本非常高的执行计划的COST变低,而容易被优化器选择。 对于上述问题可选的常见方案是若有这样问题的SQL较少则考虑加HINT或者SQL PROFILE,若较多还是需要考虑减少这种谓词左边有函数的现象。 implicit data_type conversion functions in Filter Predicates. Review Execution Plans. If Filter Predicatesinclude unexpected INTERNAL_FUNCTION to perform an implicit data_type conversion, be sure it is not preventing a column from being used as an Access Predicate.
转载于:https://www.cnblogs.com/macleanoracle/archive/2013/03/19/2968127.html
SQL调优:带函数的谓词导致CBO Cardinality计算误差相关推荐
- 这些SQL调优小技巧,你学废了吗?
推荐:本文转载自"老虎刘".敢于对技术网红文提出质疑,并给出有效评论和批复,刘哥走在了我们前面. Oracle 原厂优化组组长,严谨治学,敬畏技术,在刘哥身上,你可以看到热情,热血 ...
- SQL调优指南笔记6:Explaining and Displaying Execution Plans
本文为SQL Tuning Guide第6章"解释和显示执行计划"的笔记. 了解如何解释SQL语句并显示其计划对于 SQL 调优至关重要. 重要基本概念 row source tr ...
- oracle sql 执行计划分析_Oracle SQL调优系列之看懂执行计划explain
1.文章写作前言简介 SQL调优系列博客链接:SQL调优专栏 之前曾经拜读过<收获,不止sql调优>一书,此书是国内DBA写的一本很不错的调优类型的书,是一些很不错的调优经验的分享.虽然读 ...
- SQL调优指南笔记19:Influencing the Optimizer
本文为SQL Tuning Guide第19章"Influencing the Optimizer"的笔记. 重要基本概念 driving table The table to w ...
- oracle trim 性能,ORACLE sql调优之记录一次trim函数引发的大表全表扫描
2017年8月14日,一地市oracle相关的调度程序ETL抽取速度奇慢,sql语句每次执行平均时间要9秒左右,如果所示: 该调度过程涉及的sql语句如下: select count(*) from ...
- Oracle Hints,Oracle并行模式(Parallel) /*+parallel(t,4)*/ 在SQL调优中的重要作用
/*+parallel(t,4)*/在SQL调优中的重要作用! 2013年11月17日 12:59:24 雾里看花5566 阅读数:5422更多 个人分类: 数据库-oracle 谈谈HINT /*+ ...
- MySQL 索引和 SQL 调优手册
MySQL索引 MySQL支持诸多存储引擎,而各种存储引擎对索引的支持也各不相同,因此MySQL数据库支持多种索引类型,如BTree索引,哈希索引,全文索引等等.为了避免混乱,本文将只关注于BTree ...
- MySQL索引和SQL调优手册
MySQL索引 MySQL支持诸多存储引擎,而各种存储引擎对索引的支持也各不相同,因此MySQL数据库支持多种索引类型,如BTree索引,哈希索引,全文索引等等. 为了避免混乱,本文将只关注于BTre ...
- sql调优的几种方式_「数据库调优」屡试不爽的面试连环combo
点赞再看,养成习惯,微信搜索[三太子敖丙]关注这个互联网苟且偷生的工具人. 本文 GitHub https://github.com/JavaFamily 已收录,有一线大厂面试完整考点.资料以及我的 ...
最新文章
- json_decode的结果是null
- 需求调研计划_拆书营销管理 实施营销调研和预测需求
- getInitParameter方法
- 解决springboot不扫描@repository的问题
- sicp第一章部分习题解答
- php变量教学,PHP变量详解
- 如何让火狐浏览器兼容window.event
- Spring知识点总结-3
- python解释器的使用
- Linux shell 查找操作
- CoppeliaSim(vrep)弹簧模型
- ubuntu下将eth3改为eth0及HWaddr的修改
- 计算机硬件技术的应用毕业论文,计算机应用毕业论文.计算机分类和硬件技术发展状况.doc...
- 大咖说开源|郑振宇:通过开源手段巩固基础软件供应链
- java语言中标识符大小写不敏感_下列叙述中,正确的是()。A.Java语言的标识符是区分大小写的B.源文件名与public类名可...
- 【Python】—— pipenv使用小结
- ECharts-中国省市地图
- 最佳实践 | 如何提高落地页的转化率?这里有4个策略
- echart旭日图_基于Echarts4.0实现旭日图
- PGL图学习之图神经网络ERNIESage、UniMP进阶模型[系列八]
热门文章
- 好分数阅卷3.0_自考通过率低?一位资深阅卷老师的自述
- 数据库知识:SQLServer变量相关知识介绍
- 后端:Java中的BigDecimal类你了解多少?
- 通俗易懂,一篇文章告诉你编程语言是个啥?
- Shell重定向的概念笔记
- 某游戏在华为鸿蒙,华为鸿蒙系统运行安卓游戏出现新状况!安卓换皮论被彻底打脸?...
- Docker---问题1:bash: vi: command not found/bash: vim: command not found
- 同时获取同一等级下多个class值的节点的方法
- 幕后常驻嘉宾配音小姐姐的2021年度总结
- 入坑 Electron 开发跨平台桌面应用