Oracle 多表查询优化
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 多表查询优化的更多相关文章
- ORACLE多表查询优化
ORACLE有个高速缓冲的概念,这个高速缓冲就是存放执行过的SQL语句,那oracle在执行sql语句的时候要做很多工作,例如解析sql语句,估算索引利用率,绑定变量,读取数据块等等这些操作.假设高速 ...
- ORACLE 多表查询优化收集整理
搞WEB的离不开数据库,在一个层面上,对数据库的熟练程度决定了很多的事情. 本文就大家都纠结的ORACLE多表查询的性能问题给出一系列个优化方法,那这些都是项目中长期用到的,所以很熟,很熟,已经成为习 ...
- oracle表查询优化
ORACLE有个高速缓冲的概念,这个高速缓冲就是存放执行过的SQL语句,那oracle在执行sql语句的时候要做很多工作,例如解析sql语句,估算索引利用率,绑定变量,读取数据块等等这些操作.假设高速 ...
- Oracle的表锁死以及解锁
Oracle的表锁死以及解锁 oracle 查看锁死的表,锁死的进程. select sess.sid, sess.serial#, lo.oracle_username, lo.os_user_na ...
- 如何利用Oracle外部表导入文本文件的数据
同事最近在忙数据一致性比对工作,需要对不同文本文件中的数据进行比对,有的文件较大,记录较多,如果用普通的文本编辑器打开的话,很显然,会很卡,甚至打不开. 基于此,可将该文本文件的数据导入到数据库中,在 ...
- ORACLE外部表总结
外部表介绍 ORACLE外部表用来存取数据库以外的文本文件(Text File)或ORACLE专属格式文件.因此,建立外部表时不会产生段.区.数据块等存储结构,只有与表相关的定义放在数据字典中.外部表 ...
- Oracle新表使用序列(sequence)作为插入值,初始值不是第一个,oraclesequence
Oracle新表使用序列(sequence)作为插入值,初始值不是第一个,oraclesequence 使用oracle11g插入数据时遇到这样一个问题: 1 --创建测试表-- 2 CREATE T ...
- oracle 锁表问题
oracle执行表数据更新的时候,会遇到锁表问题,比方说,会遇到这样的问题,主要原因是这张表被其他人占用,修改数据没有提交.oracle为了避免脏数据的产生,在其安全机制下,锁住该表. 执行如下操作, ...
- oracle数据库表空间追加数据库文件方法
oracle数据库表空间追加数据库文件方法 针对非大文件方式表空间,允许追加文件进行表空间的扩展,单个文件最大大小是32G 第一种方式:表空间增加数据文件 www.2cto.com 1 ...
随机推荐
- Github for Windows使用介绍
Git已经变得非常流行,连Codeplex现在也已经主推Git.Github上更是充斥着各种高质量的开源项目,比如ruby on rails,cocos2d等等.对于习惯Windows图形界面的程序员 ...
- 基本药目录sop
http://db.yaozh.com/basicdir 基本药物 编辑 "基本药物"的概念, 由世界卫生组织于1977年提出,指的是能够满足基本医疗卫生需求,剂型适宜.保证供应. ...
- Java——不弹起的按钮组件:JToggleButton
import java.awt.GridLayout; import javax.swing.JFrame; import javax.swing.JToggleButton; //========= ...
- php Hash Table(四) Hash Table添加和更新元素
HashTable添加和更新的函数: 有4个主要的函数用于插入和更新HashTable的数据: int zend_hash_add(HashTable *ht, char *arKey, uint n ...
- @Autowired与@Resource的区别
1.@Autowired与@Resource都可以用来装配bean. 都可以写在字段上,或写在setter方法上. 2.@Autowired默认按类型装配(这个注解是属业spring的),默认情况下必 ...
- Effective Objective-C 2.0 — 第二章 对象、消息、运行期 - 第六条:理解“属性”这一概念
开发者通过对象来 存储并传递数据. 在对象之间传递数据并执行任务的过程就叫做“消息传递”. 这两条特性的工作原理? Objective-C运行期环境(Objective-C runtime) ,提供了 ...
- 登录验证码编写(jsp+servlet+dao)
一.什么是验证码及它的作用 验证码为全自动区分计算机和人类的图灵测试的缩写,是一种区分用户是计算机的公共全自动程序,这个问题可以由计算机生成并评判,但是必须只有人类才能解答. 可以防止恶意破解密码.刷 ...
- MYSQL的锁介绍,以及死锁发生情况-带例子
mysql锁能在并发情况下的mysql进行更好的优化 MySQL有三种锁的级别:页级.表级.行级,这3种锁的特性可大致归纳如下: 表级锁:开销小,加锁快:不会出现死锁:锁定粒度大,发生锁冲突的概率最高 ...
- Eclipse插件checkstyle安装使用
方法一: 1.Eclipse中,选择Help->Software Updates->Find and Install 2.选择 Search for new features to ...
- [C#基础]c#中的BeginInvoke和EndEndInvoke
摘要 异步这东西,真正用起来的时候,发现事情还是挺多的,最近在项目中用到了异步的知识,发现对它还是不了解,处理起来,走了不少弯路.觉得还是补一补还是很有必要的. MSDN原文地址:https://ms ...