网站首页
JSP空间
动态资讯
开源项目
技术文档
资源下载
J2EE资源
客户论坛
在线支付
 
  技术文档>>数据库技术>>Oracle技术>>Oracle开发>查看文档  
  如何正确的使用or展开来改写sql查询     
  文章作者:未知  文章来源:赛迪网技术社区  
  查看:155次  录入:管理员--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 dbms_job:每隔特定时间执行特定任务 08-05
statspack监控管理:定期清除1个月的数据 02-28
讲解oracle数据库10g新特性中的闪回查询 05-12
超大型oracle数据库应用系统的设计方法 (1) 05-04
oracle数据库建表脚本当中使用默认值的实例 08-15
融会贯通oracle数据库的25条基本知识 02-29
深入讲解"database link"的设置和使用 03-12
经验总结:一次oracle数据库冷备份恢复过程 08-18
轻松解决oracle 10g 的em中文乱码问题 03-07
轻松掌握Oracle中事务管理的概念 09-29
查看本用户下的各种对象的SQL脚本 01-15
细化解析如何共享Oracle数据库身份空间 09-01
为什么同机安装10g和11g后会出现连接问题 04-17
实例讲解如何使用oracle数据库to_date() 04-17
oracle数据库9i在aix环境下的性能调整 05-08
教你轻松掌握数据库链路的建立和使用 (1) 05-06
调用存储过程时注意要使用output做修饰符 04-09
Oracle OCCI的一个简单的包装类的实现 04-23
讲解oracle数据库应用程序中raid的级别 05-05
轻松掌握优化oracle网络设置的解决方案 (1) 01-25
返回首页 | 关于我们 | J网章程 | JSP空间合租 | 客服中心 | 免责声明 | 常见问题 | 参观机房
本站主机空间代理至厦门市华众网络科技有限公司
《中华人民共和国增值电信业务经营许可证》
编号:闽B2-20050079
@2005-2008福建JSP技术网 版权所有 闽ICP备05000928号
厦门(总部):13616026886 福州:0591-87655121
邮箱:admin@fjjsp.com 站长QQ,点击这里给我发消息