网站首页
JSP空间
动态资讯
开源项目
技术文档
资源下载
J2EE资源
客户论坛
在线支付
 
  技术文档>>数据库技术>>Oracle技术>>Oracle开发>查看文档  
  如何正确的使用or展开来改写sql查询     
  文章作者:未知  文章来源:赛迪网技术社区  
  查看:154次  录入:管理员--2008-03-26  
 

【赛迪网-it技术报道】问题:

下面的这条sql应该怎么优化?

select * from sys_user 
where user_code = 'zhangyong' 
or user_code in 
(select grp_code 
from sys_grp 
where sys_grp.user_code = 'zhangyong')


execution plan
----------------------------------------------------------
0  select statement optimizer=rule
1  0   filter
2  1     table access (full) of 'sys_user'
3  1     index (unique scan) of 'pk_sys_grp' (unique)


statistics
----------------------------------------------------------
14  recursive calls
4  db block gets
30590 consistent gets
0  physical reads
0  redo size
1723  bytes sent via sql*net to client
425  bytes received via sql*net from client
2  sql*net roundtrips to/from client
0  sorts (memory)
0  sorts (disk)
3  rows processed

里面的查询返回的记录数一般只有一两条,但sys_user表的数据很多,怎么样才能让这条sql以sys_grp为驱动表?

表中记录情况如下:

sql> select count(*) from sys_grp;
count(*)----------25130
sql> select count(*) from sys_user;
count(*)
----------
15190

优化:

降低逻辑读是优化sql的基本原则之一

我们尝试通过降低逻辑读来加快sql的执行.

这里我们使用or展开来改写sql查询:

select * from sys_user where user_code = 'zhangyong' 
union all
select * from sys_user where user_code <> 'zhangyong' 
and user_code in (select grp_code from sys_grp 
where sys_grp.user_code = 'zhangyong')

statistics
----------------------------------------------------------
          0  recursive calls
          0  db block gets
         130 consistent gets
          0  physical reads
          0  redo size
       1723  bytes sent via sql*net to client
        425  bytes received via sql*net from client
          2  sql*net roundtrips to/from client
          1  sorts (memory)
          0  sorts (disk)
          3  rows processed

execution plan
----------------------------------------------------------
0      select statement optimizer=rule
1    0   union-all
2    1     table access (by index rowid) of 'sys_user'
3    2       index (unique scan) of 'pk_sys_user' (unique)
4    1     nested loops
5    4       view of 'vw_nso_1'
6    5         sort (unique)
7    6           table access (by index rowid) of 'sys_grp'
8    7             index (range scan) of 'fk_sys_user_code' (non-unique)
9    4       table access (by index rowid) of 'sys_user'
10    9         index (unique scan) of 'pk_sys_user' (unique)

我们注意到,通过改写,逻辑读减少到130,从30590到130这是一个巨大的提高,减少逻辑读最终会减少资源消耗,提高sql的执行效率.

这个改写把filter改为了nest loop,索引得以充分利用.从而大大提高了性能.

我们同时注意到,这里引入了一个排序

排序来自于这一步:

----------------------------------
6  5  sort (unique)
7  6    table access (by index rowid) of 'sys_grp'
8  7   index (range scan) of 'fk_sys_user_code' (non-unique)

----------------------------------

注释:在'sys_grp'表中,user_code 是非唯一键值,在in值判断里,要做sort unique排序,去除重复值,这里的union all是不需要排序的。

 
 
上一篇: 如何用dbms_rowid获取rowid的详细信息    下一篇: 如何使用pl/sql读取数据库中的blob对象
  相关文档
oracle数据库中如何建立二进制文件索引 (1) 03-24
教你通过sql语句获取数据库的基本信息 07-29
如何在oracle数据库中使用java存储过程 08-12
解析Oracle的操作系统项目Raw Iron计划 09-01
oracle存储过程及table表用pl/sql备份还原 08-16
如何为用户提供回滚操作时间的准确评估 01-29
讲解oracle中job与存储过程的接合用法 03-13
修改默认的oracle xml database监听端口 05-12
轻松掌握oralce数据库常用预定义的例外 04-03
如何使用dbms_repair检测和修补数据坏块 (1) 05-05
oracle数据库连接池下如何跟踪终端会话 (1) 04-16
Oracle Online Redo LogFile 09-29
通过rownum隐式游标实现与top相似的功能 04-21
用Oracle 10g新的行时间戳捕捉变化 04-11
红旗linux和Oracle10gr2的冲突 05-27
Oracle-Decode()函数和CASE语句的比较 06-03
教你如何使用Logmnr方法分析数据库日志 06-03
影响oracle数据库系统性能的初始化参数 11-19
详细讲解oracle数据库后台进程的具体功能 (1) 04-28
轻松掌握分布式数据库全局名与数据库链 09-29
返回首页 | 关于我们 | J网章程 | JSP空间合租 | 客服中心 | 免责声明 | 常见问题 | 参观机房
本站主机空间代理至厦门市华众网络科技有限公司
《中华人民共和国增值电信业务经营许可证》
编号:闽B2-20050079
@2005-2008福建JSP技术网 版权所有 闽ICP备05000928号
厦门(总部):13616026886 福州:0591-87655121
邮箱:admin@fjjsp.com 站长QQ,点击这里给我发消息