[20191206]nvl与非空约束.txt --//优化1个项目,发现开发大量在谓词里面使用nvl函数.感觉这个项目在前期规划混乱.语句谓词里面大量出现 --//类似flag=1,或者nvl(flag,0)=1这样的语句.这样我要优化这样语句必须建立2套索引,是否可以通过约束设置 --//该列非空(当然必须没有null值的情况),取消这个限制,测试看看. 1.环境: SCOTT@book> @ ver1 PORT_STRING VERSION BANNER ------------------------------ -------------- ---------------------------------------------------------------------------- x86_64/Linux 2.4.xx 11.2.0.4.0 Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production SCOTT@book> create table t as select rownum id ,lpad('a',100,'a') text,0 flag from dual connect by level<=1e5; Table created. SCOTT@book> @desc t Name Null? Type ----- -------- ------------- ID NUMBER TEXT VARCHAR2(100) FLAG NUMBER --//flag字段没有约束. SCOTT@book> update t set flag=1 where id=1e5; 1 row updated. SCOTT@book> commit ; Commit complete. SCOTT@book> create index i_t_flag on t(flag); Index created. SCOTT@book> execute sys.dbms_stats.gather_table_stats ( OwnName => user,TabName => 't',Estimate_Percent => NULL,Method_Opt => 'FOR COLUMNS flag SIZE 2 ',Cascade => True ,No_Invalidate => false) PL/SQL procedure successfully completed. --//在flag字段上建立直方图. 2.测试1: SCOTT@book> alter session set statistics_level=all ; Session altered. SCOTT@book> select * from t where nvl(flag,0)=1; ID TEXT FLAG ---------- ---------------------------------------------------------------------------------------------------- ---------- 100000 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 1 SCOTT@book> @ dpc '' '' PLAN_TABLE_OUTPUT ------------------------------------- SQL_ID gg2nkuddjjhyz, child number 1 ------------------------------------- select * from t where nvl(flag,0)=1 Plan hash value: 1601196873 -------------------------------------------------------------------------------------------------------------------- | Id | Operation | Name | Starts | E-Rows |E-Bytes| Cost (%CPU)| E-Time | A-Rows | A-Time | Buffers | -------------------------------------------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | | | 436 (100)| | 1 |00:00:00.02 | 1567 | |* 1 | TABLE ACCESS FULL| T | 1 | 1 | 108 | 436 (1)| 00:00:06 | 1 |00:00:00.02 | 1567 | -------------------------------------------------------------------------------------------------------------------- Query Block Name / Object Alias (identified by operation id): ------------------------------------------------------------- 1 - SEL$1 / T@SEL$1 Predicate Information (identified by operation id): --------------------------------------------------- 1 - filter(NVL("FLAG",0)=1) --//你可以发现在谓词使用nvl(flag,0)=1;E-rows估计也很正确.但是就是不能使用索引. 3.测试2: SCOTT@book> alter table t modify(flag not null); Table altered. SCOTT@book> select * from t where nvl(flag,0)=1; ID TEXT FLAG ---------- ---------------------------------------------------------------------------------------------------- ---------- 100000 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 1 SCOTT@book> @ dpc '' '' PLAN_TABLE_OUTPUT ------------------------------------- SQL_ID gg2nkuddjjhyz, child number 1 ------------------------------------- select * from t where nvl(flag,0)=1 Plan hash value: 120143814 ---------------------------------------------------------------------------------------------------------------------------------- | Id | Operation | Name | Starts | E-Rows |E-Bytes| Cost (%CPU)| E-Time | A-Rows | A-Time | Buffers | ---------------------------------------------------------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | | | 2 (100)| | 1 |00:00:00.01 | 3 | | 1 | TABLE ACCESS BY INDEX ROWID| T | 1 | 1 | 108 | 2 (0)| 00:00:01 | 1 |00:00:00.01 | 3 | |* 2 | INDEX RANGE SCAN | I_T_FLAG | 1 | 1 | | 1 (0)| 00:00:01 | 1 |00:00:00.01 | 2 | ---------------------------------------------------------------------------------------------------------------------------------- Query Block Name / Object Alias (identified by operation id): ------------------------------------------------------------- 1 - SEL$1 / T@SEL$1 2 - SEL$1 / T@SEL$1 Predicate Information (identified by operation id): --------------------------------------------------- 2 - access("FLAG"=1) --//可以发现这样可以使用I_T_FLAG,注意看Predicate Information (identified by operation id): --//2 - access("FLAG"=1),不再出现nvl函数. --//当然我必须处理相关记录修改有null替换为缺省值. --//如果写成select * from t where nvl(flag,0)=0; 过滤条件是filter("FLAG"=0). --//实际上开发写代码也没有仔细想想nvl(flag,0)=1,flag是NULL或者0不可能等于1.也可以讲oracle优化器不够智能.修改条件为flag=1. --//仅仅查询nvl(flag,0)=0才需要这样写. --//实际上开发写代码时有一条特殊规定在谓词中使用函数一定要小心.我曾经跟开发开玩笑地讲to_date,trunc之类的函数不是给开发用 --//的.而是给dba用的.可惜这样的错误一犯再犯,一群长不大的群体....
[20191206]nvl与非空约束.txt
来源:这里教程网
时间:2026-03-03 14:40:34
作者:
编辑推荐:
- [20191206]nvl与非空约束.txt03-03
- read by other session导致oracle性能低03-03
- windows7 安装与卸载 oracle 11G03-03
- LIST INCARNATION OF DATABASE含义03-03
- [20191202]关于oracle实例是否使用hugepages问题.txt03-03
- [20191129]ALTER TABLE MINIMIZE RECORDS_PER_BLOCK.txt03-03
- ORACLE DATAGUARD灾备归档空间满导致的ORA-00600 [2619]03-03
- 一次sql改写优化案例03-03
下一篇:
相关推荐
-
雷神推出 MIX PRO II 迷你主机:基于 Ultra 200H,玻璃上盖 + ARGB 灯效
2 月 9 日消息,雷神 (THUNDEROBOT) 现已宣布推出基于英
-
制造商 Musnap 推出彩色墨水屏电纸书 Ocean C:支持手写笔、第三方安卓应用
2 月 10 日消息,制造商 Musnap 现已在海外推出一款 Oce
热文推荐
- windows7 安装与卸载 oracle 11G
windows7 安装与卸载 oracle 11G
26-03-03 - LIST INCARNATION OF DATABASE含义
LIST INCARNATION OF DATABASE含义
26-03-03 - 最佳实践 | 数据库迁云解决方案选型 & 流程全解析
最佳实践 | 数据库迁云解决方案选型 & 流程全解析
26-03-03 - Oracle date 类型比较和String比较
Oracle date 类型比较和String比较
26-03-03 - OPPO用户怎么让手机变流畅?花1分钟关闭这4个设置,瞬间变流畅
OPPO用户怎么让手机变流畅?花1分钟关闭这4个设置,瞬间变流畅
26-03-03 - 4 个概念,1 个动作,让应用管理变得更简单
4 个概念,1 个动作,让应用管理变得更简单
26-03-03 - 如何分析及处理 Flink 反压?
如何分析及处理 Flink 反压?
26-03-03 - 基于 Flink 的实时数仓生产实践
基于 Flink 的实时数仓生产实践
26-03-03 - 中报背后的阿里影业:互联网影视如何沉淀平台方法论
中报背后的阿里影业:互联网影视如何沉淀平台方法论
26-03-03 - oracle 报大小写错误
oracle 报大小写错误
26-03-03
