ORACLE有个高速缓冲的概念,这个高速缓冲就是存放执行过的SQL语句,那oracle在执行sql语句的时候要做很多工作,例如解析sql语句,估算索引利用率,绑定变量,读取数据块等等这些操作。假设高速缓冲里已经存储了执行过的sql语句,那就直接匹配执行了,少了步骤,自然就快了,但是经过测试会发现高速缓冲只对简单的表起作用,多表的情况完全没有效果,例如在查询单表的时候那叫一个快,但是假设连接多个表,就龟速了。
最重要一点,ORACLE的高速缓冲是全字符匹配的,什么意思呢,看下面三个select

--No.1
select * from tableA;
--No.2
select * From tableA;
--No.3
select * from tableA;

这三个语句乍一看是一样的,但是高速缓存是不认的,是全字符匹配的,索引在高速缓存里会存储三条不同的语句,说到这里,又引出一个习惯,就是要保持良好的编程习惯,这个很重要

ORACLE多表优化我积累了一些,都是常用的,介绍下

一、FROM子句后面的表顺序有讲究

先说为啥,ORACLE在解析sql语句的时候对FROM子句后面的表名是从右往左解析的,是先扫描最右边的表,然后在扫描左边的表,然后用左边的表匹配数据,匹配成功后就合并。 所以,在对多表查询中,一定要把小表写在最右边,为什么自己想想就明白了。例如下面的两个语句:

--No.1  tableA:100w条记录  tableB:1w条记录 执行速度十秒
select count(*) from tableA, tableB; --No.2 执行速度百秒甚至更高
select count(*) from tableB, tableA;

这个估计很多人都知道,但是要确认非常有用。

还有一种是三张表的查询,例如

select count(1) from tableA a,tableB b ,tableC c where a.id=b.id and a.id=c.id;

上面中tableA 为交叉表,根据oracle对From子句从右向左的扫描方式,应该把交叉表放在最末尾,然后才是最小表,所以上面的应该这样写

--tableA a 交叉表 
--tabelB b 100w
--tableC c 1w
select count(1) from tableB b ,tableC c ,tableA a where a.id=b.id and a.id=c.id;

这种写法对大数据量会非常有用,大家谨记,也是很常用的。

二、Where子句后面的条件过滤有讲究,ORACLE对where子句后面的条件过滤是自下向上,从右向左扫描的,所以和From子句一样一样的,把过滤条件排个序,按过滤数据的大小,自然就是最少数据的那个条件写在最下面,最右边,依次类推,例如

--No.1 不可取 性能低下
select * from tableA a where
a.id>500
and a.lx = '2b'
and a.id < (select count(1) from tableA where id=a.id) --No.2 性能高
select * from tableA a where
a.id < (select count(1) from tableA where id=a.id)
and a.id>500
and a.lx = '2b'

三、使用select的时候少用*,多敲敲键盘,写上字段名吧,因为ORACLE的查询器会把*转换为表的全部列名,这个会浪费时间的,所以在大表中少用

四、充分利用rowid ,可以用rowid来分页,删除查询重复记录,很强大的,给两个例子:

--oracle查找重复记录
select * from tableA a where a.rowid>=(select min(rowid) from tableB b where a.column=b.column) --oracle删除重复记录
delete from tableA a where a.rowid>=(select min(rowid) from tableB b where a.column=b.column) --分页 start=10 limit=10
--end 为 start + limit
--1.查询要排列的表A
--2.查询A表的Rownum找出小于end的数据组成表B
--3.查询B表通过rownum找出大于start的数据完成
--简单的说先根据end值过滤数据,然后在根据start过滤数据
SELECT * FROM
(SELECT a.*, ROWNUM rn FROM (SELECT * FROM uim_serv_file_data ORDER BY OUID) a where ROWNUM<=20) b
where rn>10 order by ouid desc

五、存储过程中需要注意的,多用commit了,既可以释放资源,但是要谨慎。

六、减少对数据库表的查询,这个很重要,能减少就减少,因为在执行语句的时候oracle会做很多初始工作。

七、少用in,多用exists来代替

--NO.1  IN的写法  
SELECT * FROM TABLEA A WHERE
A.ID IN (SELECT ID FORM TABLEB B WHERE B.ID>1) --NO.2 exists 写法
SELECT * FROM TABLEA A WHERE
EXISTS (SELECT 1 FROM TABLEB B WHERE A.ID=B.ID AND B.ID>1)

ORACLE多表查询优化的更多相关文章

  1. Oracle 多表查询优化

    ORACLE有个高速缓冲的概念,这个高速缓冲就是存放执行过的SQL语句,那oracle在执行sql语句的时候要做很多工作,例如解析sql语句,估算索引利用率,绑定变量,读取数据块等等这些操作.假设高速 ...

  2. ORACLE 多表查询优化收集整理

    搞WEB的离不开数据库,在一个层面上,对数据库的熟练程度决定了很多的事情. 本文就大家都纠结的ORACLE多表查询的性能问题给出一系列个优化方法,那这些都是项目中长期用到的,所以很熟,很熟,已经成为习 ...

  3. oracle表查询优化

    ORACLE有个高速缓冲的概念,这个高速缓冲就是存放执行过的SQL语句,那oracle在执行sql语句的时候要做很多工作,例如解析sql语句,估算索引利用率,绑定变量,读取数据块等等这些操作.假设高速 ...

  4. Oracle的表锁死以及解锁

    Oracle的表锁死以及解锁 oracle 查看锁死的表,锁死的进程. select sess.sid, sess.serial#, lo.oracle_username, lo.os_user_na ...

  5. 如何利用Oracle外部表导入文本文件的数据

    同事最近在忙数据一致性比对工作,需要对不同文本文件中的数据进行比对,有的文件较大,记录较多,如果用普通的文本编辑器打开的话,很显然,会很卡,甚至打不开. 基于此,可将该文本文件的数据导入到数据库中,在 ...

  6. ORACLE外部表总结

    外部表介绍 ORACLE外部表用来存取数据库以外的文本文件(Text File)或ORACLE专属格式文件.因此,建立外部表时不会产生段.区.数据块等存储结构,只有与表相关的定义放在数据字典中.外部表 ...

  7. Oracle新表使用序列(sequence)作为插入值,初始值不是第一个,oraclesequence

    Oracle新表使用序列(sequence)作为插入值,初始值不是第一个,oraclesequence 使用oracle11g插入数据时遇到这样一个问题: 1 --创建测试表-- 2 CREATE T ...

  8. oracle 锁表问题

    oracle执行表数据更新的时候,会遇到锁表问题,比方说,会遇到这样的问题,主要原因是这张表被其他人占用,修改数据没有提交.oracle为了避免脏数据的产生,在其安全机制下,锁住该表. 执行如下操作, ...

  9. oracle数据库表空间追加数据库文件方法

    oracle数据库表空间追加数据库文件方法   针对非大文件方式表空间,允许追加文件进行表空间的扩展,单个文件最大大小是32G  第一种方式:表空间增加数据文件    www.2cto.com   1 ...

随机推荐

  1. python的random模块

    As an example of subclassing, the random module provides the WichmannHill class that implements an a ...

  2. mysql 报错之创建自定义函数

    I experienced this error while trying to alter one of my stored procedures remotely on a master serv ...

  3. MEF 编程指南(一):在应用中托管 MEF

    在应用程序中托管(Hosing) MEF 涉及到创建组合容器(CompositionContainer) 实例,添加可组合部件(Composable Parts),包括应用程序宿主(Host)本身并进 ...

  4. Openfire服务器MySQL优化

    Openfire服务器MySQL优化: [root@iZ28g4ctd7tZ ~]# mysql -u root -p XXXXX mysql> show processlist; +----- ...

  5. MRuby 编译笔记

    专注于嵌入式脚本的MRuby在Windows下的编译笔记: 环境: OS: Windows 8.1, 使用 VS Express 2013 for Desktop. 材料: MRuby : 下载源码就 ...

  6. Android 事件监听处理

    事件监听的处理模型包括三个成员:事件源.事件以及事件监听器. 基于监听的事件处理模型一般包括几个步骤: 1.获取普通界面组件: 2.实现事件监听器类 3.将监听器对象注冊给普通组件 当事件源上发生指定 ...

  7. NGUI panel使用soft clip时,屏幕缩放后无法正常工作的问题解决

    最近开始使用NGUI,通过查找,搞定了屏幕缩放问题,但在用到panel的soft clip时,碰到了问题,NGUI给出了警告 “clipped panels must have a uniform s ...

  8. Cloudera集群中提交Spark任务出现java.lang.NoSuchMethodError: org.apache.hadoop.hbase.HTableDescriptor.addFamily错误解决

    Cloudera及相关的组件版本 Cloudera: 5.7.0 Hbase: 1.20 Hadoop: 2.6.0 ZooKeeper: 3.4.5 就算是引用了相应的组件依赖,依然是报一样的错误! ...

  9. Helpers\Request

    Helpers\Request The Helpers\Request class is used for detecting the type of request and retrieving t ...

  10. Asp.Net 之 服务器端控件与客户端控件的区别

    服务器控件,即Asp.Net的控件,控制这些控件必须经过服务器处理,然后响应用户,代码在服务器端解释执行,生成根据用户的浏览器而定的html元素. 客户端控件,即普通Html控件,使用script控制 ...