oracle用UNION替换OR (适用于索引列)
通常情况下, 用UNION替换WHERE子句中的OR将会起到较好的效果. 对索引列使用OR将造成全表扫描. 注意, 以上规则只针对多个索引列有效. 如果有column没有被索引, 查询效率可能会因为你没有选择OR而降低.
在下面的例子中, LOC_ID 和REGION上都建有索引.
高效:
SELECT LOC_ID , LOC_DESC , REGION
FROM LOCATION
WHERE LOC_ID = 10
UNION
SELECT LOC_ID , LOC_DESC , REGION
FROM LOCATION
WHERE REGION = “MELBOURNE”
低效:
SELECT LOC_ID , LOC_DESC , REGION
FROM LOCATION
WHERE LOC_ID = 10 OR REGION = “MELBOURNE”
如果你坚持要用OR, 那就需要返回记录最少的索引列写在最前面.
注意:
WHERE KEY1 = 10 (返回最少记录)
OR KEY2 = 20 (返回最多记录)
ORACLE 内部将以上转换为
WHERE KEY1 = 10 AND
((NOT KEY1 = 10) AND KEY2 = 20)
下面的测试数据仅供参考: (a = 1003 返回一条记录 , b = 1 返回1003条记录)
SQL> select * from unionvsor /*1st test*/
2 where a = 1003 or b = 1;
1003 rows selected.
Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE
1 0 CONCATENATION
2 1 TABLE ACCESS (BY INDEX ROWID) OF 'UNIONVSOR'
3 2 INDEX (RANGE SCAN) OF 'UB' (NON-UNIQUE)
4 1 TABLE ACCESS (BY INDEX ROWID) OF 'UNIONVSOR'
5 4 INDEX (RANGE SCAN) OF 'UA' (NON-UNIQUE)
Statistics
----------------------------------------------------------
0 recursive calls
0 db block gets
144 consistent gets
0 physical reads
0 redo size
63749 bytes sent via SQL*Net to client
7751 bytes received via SQL*Net from client
68 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
1003 rows processed
SQL> select * from unionvsor /*2nd test*/
2 where b = 1 or a = 1003 ;
1003 rows selected.
Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE
1 0 CONCATENATION
2 1 TABLE ACCESS (BY INDEX ROWID) OF 'UNIONVSOR'
3 2 INDEX (RANGE SCAN) OF 'UA' (NON-UNIQUE)
4 1 TABLE ACCESS (BY INDEX ROWID) OF 'UNIONVSOR'
5 4 INDEX (RANGE SCAN) OF 'UB' (NON-UNIQUE)
Statistics
----------------------------------------------------------
0 recursive calls
0 db block gets
143 consistent gets
0 physical reads
0 redo size
63749 bytes sent via SQL*Net to client
7751 bytes received via SQL*Net from client
68 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
1003 rows processed
SQL> select * from unionvsor /*3rd test*/
2 where a = 1003
3 union
4 select * from unionvsor
5 where b = 1;
1003 rows selected.
Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE
1 0 SORT (UNIQUE)
2 1 UNION-ALL
3 2 TABLE ACCESS (BY INDEX ROWID) OF 'UNIONVSOR'
4 3 INDEX (RANGE SCAN) OF 'UA' (NON-UNIQUE)
5 2 TABLE ACCESS (BY INDEX ROWID) OF 'UNIONVSOR'
6 5 INDEX (RANGE SCAN) OF 'UB' (NON-UNIQUE)
Statistics
----------------------------------------------------------
0 recursive calls
0 db block gets
10 consistent gets
0 physical reads
0 redo size
63735 bytes sent via SQL*Net to client
7751 bytes received via SQL*Net from client
68 SQL*Net roundtrips to/from client
1 sorts (memory)
0 sorts (disk)
1003 rows processed
用UNION的效果可以从consistent gets和 SQL*NET的数据交换量的减少看出
oracle用UNION替换OR (适用于索引列)的更多相关文章
- 【转】Oracle索引列NULL值引发执行计划该表的测试示例
有时开发进行表结构设计,对表字段是否为空过于随意,出现诸如id1=id2,如果允许字段为空,因为Oracle中空值并不等于空值,有可能得到意料之外的结果.除此之外,最关键的是,NULL会影响oracl ...
- oracle避免改变索引列的类型
当比较不同数据类型的数据时, ORACLE自动对列进行简单的类型转换. 假设 EMPNO是一个数值类型的索引列. SELECT … FROM EMP WHERE EMPNO = ‘123’ 实际上,经 ...
- oracle避免在索引列上使用IS NULL和IS NOT NULL
避免在索引中使用任何可以为空的列,ORACLE将无法使用该索引 .对于单列索引,如果列包含空值,索引中将不存在此记录. 对于复合索引,如果每个列都为空,索引中同样不存在此记录. 如果至少有一个列不为空 ...
- oracle避免在索引列上使用NOT
通常, 我们要避免在索引列上使用NOT, NOT会产生在和在索引列上使用函数相同的 影响. 当ORACLE”遇到”NOT,他就会停止使用索引转而执行全表扫描. 举例: 低效: (这里,不使用索引) S ...
- oracle避免在索引列上使用计算
WHERE子句中,如果索引列是函数的一部分.优化器将不使用索引而使用全表扫描. 举例: 低效: SELECT … FROM DEPT WHERE SAL * 12 > 25000; 高效: SE ...
- Oracle中Union与Union All的区别(适用多个数据库)
Oracle中Union与Union All的区别(适用多个数据库) 如果我们需要将两个select语句的结果作为一个整体显示出来,我们就需要用到union或者union all关键字.union(或 ...
- oracle中union和union all区别与性能分析
[ 概要 ] 经常写sql的同学可能会用到union和union all这两个关键词, 可能你知道使用它们可以将两个查询的结果集进行合并, 那么二者有什么区别呢? 下面我们就简单的分析下. [ 比较 ...
- Oracle学习总结_day06_视图&序列&索引
本文为博主辛苦总结,希望自己以后返回来看的时候理解更深刻,也希望可以起到帮助初学者的作用. 转载请注明 出自 : luogg的博客园 谢谢配合! day 06 视图,索引,序列 视图 什么是视图: 视 ...
- oracle数据库什么情况下创建索引比较好
索引就好象一本字典的目录.凭借字典的目录,我们可以非常迅速的找到我们所需要的条目.数据库也是如此.凭借Oracle数据库的索引,相关语句可以迅速的定位记录的位置,而不必去定位整个表. 虽 然说,在表中 ...
随机推荐
- oracle之FUNCTION拙见
一.介绍 函数(Function)为一命名的存储程序,可带参数(有无均可),有返回值 函数和过程的结构类似,但必须有一个RETURN子句,用于返回函数值. 函数说明要指定函数名.返回值的类型,以及参数 ...
- JS中int和string的转换
1.int型转换成string型 (1) var x=100 a = x.toString() (2) var x=100; a = x +"& ...
- Spring 的初次见面
简介: Spring Framework 是一个开源的企业级应用程序框架,为构建满足企业级需求的应用程序提供了大量的工具集.推出该框架的原因是在时候用J2EE进行开发是会提高复杂性. Spring三大 ...
- C# Socket流数据大小端读写封装
网络数据是大端模式,而c#中的数据小端结构,那么在读写网络数据的时候需要进行转换.c#类库IPAddress已经封装了大小端的转换. 封装代码如下: using System.IO; using ...
- Android平台本地(离线)打包指南 - Android Studio
预备环境 AndroidStudio开发环境,要求安装Android4.0或以上(API 14)SDK. 下载HBuilder离线打包Android版SDK(5+ SDK下载). 离线打包SDK目录说 ...
- 用蒙特卡罗方法解非线性规划MATLAB
共需要三个M文件,主程序为randlp.m randlp.m: function [sol,r1,r2]=randlp(a,b,n) %随机模拟解非线性规划 debug=1; a=0; %试验点下界 ...
- Spring Boot → 08:嵌入式Servlet容器自定义
Spring Boot → 08:嵌入式Servlet容器自定义
- 视觉暂留-Info:这些神奇的“视觉暂留”动画,每一幅都让人拍案叫绝!
ylbtech-视觉暂留-Info:这些神奇的“视觉暂留”动画,每一幅都让人拍案叫绝! 1.返回顶部 1. 这些神奇的“视觉暂留”动画,每一幅都让人拍案叫绝! 原创|发布:2018-05-28 19: ...
- day39-Spring 08-Spring的AOP:基于AspectJ的注解
基于AspectJ的注解的开发要重点掌握. 这些表达式肯定要应用在我们的某些个增强上. 学习AspectJ也是两种形式:一种是XML,一种是注解.AspectJ的增强,就是那些通知的类型.Aspect ...
- 2019-9-2-dotnet-命名管道名字长度限制
title author date CreateTime categories dotnet 命名管道名字长度限制 lindexi 2019-09-02 11:54:50 +0800 2019-09- ...