oracle union的替代方案,用UNION ALL 替代OR 优化SQL (EYGLE)

本文详细介绍了如何通过改写SQL查询来优化性能,将一个涉及大量逻辑读的查询从30590降低到130。通过将OR条件拆分为UNION ALL,并利用索引,显著提高了查询效率。改写后的SQL使用了NESTED LOOPS,避免了多余的排序操作,进一步提升了执行速度。
摘要由CSDN通过智能技术生成

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是不需要排序的

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值