Oracle SQL 'or' 的优化,最近的案例一则。

本文通过一个具体案例展示了如何在Oracle数据库中使用Union All替代Or条件来优化SQL查询性能,显著降低了查询成本并减少了资源消耗。
Oracle 中or是可以用union/union all来作优化的[@more@]

SQL Tuning OR的优化。

今天公司某Production DB时常LOADING飚起来,Monitor下发现一个很highSQL:

SELECT COUNT(A.ISN) FROM MO_ROUTE A,MO B WHERE (A.ROUTE = :B2 OR A.ROUTE = 'LNBR') AND A.GRP = 'AI1' AND (A.MO LIKE 'NFPQ%' OR A.MO LIKE 'NF1Q%' OR A.MO LIKE 'NF6Q%') AND A.MO = B.MO(+) AND A.INTIME BETWEEN :B1 - 1 AND :B1 AND B.CDATE BETWEEN :B1 - 1 AND :B1

PLAN如下:

Execution Plan

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

0 SELECT STATEMENT Optimizer=CHOOSE (Cost=2195 Card=1 Bytes=49

)

1 0 SORT (AGGREGATE)

2 1 FILTER

3 2 NESTED LOOPS (Cost=2195 Card=1 Bytes=49)

4 3 PARTITION RANGE (ITERATOR)

5 4 PARTITION HASH (ALL)

6 5 TABLE ACCESS (BY LOCAL INDEX ROWID) OF 'MO_ROUTE

' (Cost=2194 Card=1 Bytes=30)

7 6 INDEX (RANGE SCAN) OF 'MO_ROUTE11' (NON-UNIQUE

) (Cost=1242 Card=1741)

8 3 TABLE ACCESS (BY INDEX ROWID) OF 'MO' (Cost=1 Card=1

Bytes=19)

9 8 INDEX (UNIQUE SCAN) OF 'MO1' (UNIQUE)

Statistics

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

0 recursive calls

0 db block gets

39135 consistent gets

25654 physical reads

106180 redo size

521 bytes sent via SQL*Net to client

656 bytes received via SQL*Net from client

2 SQL*Net roundtrips to/from client

0 sorts (memory)

0 sorts (disk)

1 rows processed

很好,很强大的Gets,这可是OLTP环境。

MO_ROUTE是一个RANGE-HASH Partitioned TableINTIME作为进行RANGEColumn.PLAN可以看出,经过了Partition Pruning,再走MO_ROUTE11这个INDEX MO_ROUTE11是一个Complex Index,以Intime为首列(Intime,section,grp)。看起来选则的比较有道理。

然而这个Table即使是一天的数据量也很大。这个时侯注意到MO,MO的可选择性应该也是比较强的。

+HINT看一下:

SELECT /*+INDEX(A MO_ROUTE2)*/COUNT(A.ISN) FROM MO_ROUTE A,MO B WHERE

(A.ROUTE = 'VNMB'OR A.ROUTE = 'LNBR') AND A.GRP = 'AI1'

AND (A.MO LIKE 'NFPQ%' OR A.MO LIKE 'NF1Q%' OR A.MO LIKE 'NF6Q%')

AND A.MO = B.MO(+) AND A.INTIME BETWEEN sysdate - 1 AND sysdate

AND B.CDATE BETWEEN sysdate - 1 AND sysdate

EXPLAN:

SELECT STATEMENT, GOAL = CHOOSE Cost=7414 Cardinality=1 Bytes=49

SORT AGGREGATE Cardinality=1 Bytes=49

CONCATENATION

FILTER

NESTED LOOPS Cost=85 Cardinality=1 Bytes=49

PARTITION RANGE ITERATOR

PARTITION HASH ALL

TABLE ACCESS BY LOCAL INDEX ROWID Object owner=TP Object name=MO_ROUTE Cost=84 Cardinality=1 Bytes=30

INDEX RANGE SCAN Object owner=TP Object name=MO_ROUTE2 Cost=66 Cardinality=17

TABLE ACCESS BY INDEX ROWID Object owner=TP Object name=MO Cost=1 Cardinality=1 Bytes=19

INDEX UNIQUE SCAN Object owner=TP Object name=MO1 Cardinality=1

FILTER

NESTED LOOPS Cost=85 Cardinality=1 Bytes=49

PARTITION RANGE ITERATOR

PARTITION HASH ALL

TABLE ACCESS BY LOCAL INDEX ROWID Object owner=TP Object name=MO_ROUTE Cost=84 Cardinality=1 Bytes=30

INDEX RANGE SCAN Object owner=TP Object name=MO_ROUTE2 Cost=66 Cardinality=17

TABLE ACCESS BY INDEX ROWID Object owner=TP Object name=MO Cost=1 Cardinality=1 Bytes=19

INDEX UNIQUE SCAN Object owner=TP Object name=MO1 Cardinality=1

FILTER

NESTED LOOPS Cost=85 Cardinality=1 Bytes=49

PARTITION RANGE ITERATOR

PARTITION HASH ALL

TABLE ACCESS BY LOCAL INDEX ROWID Object owner=TP Object name=MO_ROUTE Cost=84 Cardinality=1 Bytes=30

INDEX RANGE SCAN Object owner=TP Object name=MO_ROUTE2 Cost=66 Cardinality=17

TABLE ACCESS BY INDEX ROWID Object owner=TP Object name=MO Cost=1 Cardinality=1 Bytes=19

INDEX UNIQUE SCAN Object owner=TP Object name=MO1 Cardinality=1

COST变成7K多,而且实际过程中我只能把它CANCEL掉,否则Server Loading会一下子飙起来。

计划里只是到最后的总COST很高,单步的COST却较小。

于是想到用Union All来替代OR:

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

select sum(c.n) from

(SELECT COUNT(A.ISN) n FROM MO_ROUTE A,MO B WHERE

(A.ROUTE = 'VNMB' OR A.ROUTE = 'LNBR') AND A.GRP = 'AI1'

AND A.MO LIKE 'NFPQ%'

AND A.MO = B.MO(+) AND A.INTIME BETWEEN sysdate - 1 AND sysdate

AND B.CDATE BETWEEN sysdate - 1 AND sysdate

union all

SELECT COUNT(A.ISN) n FROM MO_ROUTE A,MO B WHERE

(A.ROUTE = 'VNMB' OR A.ROUTE = 'LNBR') AND A.GRP = 'AI1'

AND A.MO LIKE 'NF1Q%'

AND A.MO = B.MO(+) AND A.INTIME BETWEEN sysdate - 1 AND sysdate

AND B.CDATE BETWEEN sysdate - 1 AND sysdate

union all

SELECT COUNT(A.ISN) n FROM MO_ROUTE A,MO B WHERE

(A.ROUTE = 'VNMB' OR A.ROUTE = 'LNBR') AND A.GRP = 'AI1'

AND A.MO LIKE 'NF6Q%'

AND A.MO = B.MO(+) AND A.INTIME BETWEEN sysdate - 1 AND sysdate

AND B.CDATE BETWEEN sysdate - 1 AND sysdate) c

Execution Plan

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

0 SELECT STATEMENT Optimizer=CHOOSE (Cost=216 Card=1 Bytes=13)

1 0 SORT (AGGREGATE)

2 1 VIEW (Cost=216 Card=3 Bytes=39)

3 2 UNION-ALL

4 3 SORT (AGGREGATE)

5 4 FILTER

6 5 TABLE ACCESS (BY LOCAL INDEX ROWID) OF 'MO_ROUTE

' (Cost=69 Card=1 Bytes=30)

7 6 NESTED LOOPS (Cost=72 Card=1 Bytes=49)

8 7 TABLE ACCESS (BY INDEX ROWID) OF 'MO' (Cost=

3 Card=1 Bytes=19)

9 8 INDEX (RANGE SCAN) OF 'MO1' (UNIQUE) (Cost

=2 Card=1)

10 7 PARTITION RANGE (ITERATOR)

11 10 PARTITION HASH (ALL)

12 11 INDEX (RANGE SCAN) OF 'MO_ROUTE2' (NON-U

NIQUE) (Cost=65 Card=3)

13 3 SORT (AGGREGATE)

14 13 FILTER

15 14 TABLE ACCESS (BY LOCAL INDEX ROWID) OF 'MO_ROUTE

' (Cost=69 Card=1 Bytes=30)

16 15 NESTED LOOPS (Cost=72 Card=1 Bytes=49)

17 16 TABLE ACCESS (BY INDEX ROWID) OF 'MO' (Cost=

3 Card=1 Bytes=19)

18 17 INDEX (RANGE SCAN) OF 'MO1' (UNIQUE) (Cost

=2 Card=1)

19 16 PARTITION RANGE (ITERATOR)

20 19 PARTITION HASH (ALL)

21 20 INDEX (RANGE SCAN) OF 'MO_ROUTE2' (NON-U

NIQUE) (Cost=65 Card=3)

22 3 SORT (AGGREGATE)

23 22 FILTER

24 23 TABLE ACCESS (BY LOCAL INDEX ROWID) OF 'MO_ROUTE

' (Cost=69 Card=1 Bytes=30)

25 24 NESTED LOOPS (Cost=72 Card=1 Bytes=49)

26 25 TABLE ACCESS (BY INDEX ROWID) OF 'MO' (Cost=

3 Card=1 Bytes=19)

27 26 INDEX (RANGE SCAN) OF 'MO1' (UNIQUE) (Cost

=2 Card=1)

28 25 PARTITION RANGE (ITERATOR)

29 28 PARTITION HASH (ALL)

30 29 INDEX (RANGE SCAN) OF 'MO_ROUTE2' (NON-U

NIQUE) (Cost=65 Card=3)

Statistics

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

0 recursive calls

0 db block gets

2592 consistent gets

49 physical reads

1336 redo size

517 bytes sent via SQL*Net to client

656 bytes received via SQL*Net from client

2 SQL*Net roundtrips to/from client

0 sorts (memory)

0 sorts (disk)

1 rows processed

COST降低到200多点,Buffer GetsPhysical reads大幅度减少。

Tuning的目标达成。

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/10856805/viewspace-1007639/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/10856805/viewspace-1007639/

1. MT7620N路由器硬件组成:MT7620N路由器基于Mediatek MT7620芯片,该芯片具备完整的无线路由器功能,包括无线接入点(AP)和路由功能。MT7620芯片特点包括: - 集成IEEE802.11n MAC/基带/2.4GHz射频模块,提供无线网络接入。 - 内置580MHz MIPS 24K处理器,高效处理数据传输和路由任务。 - 集成5端口百兆以太网交换机,实现有线网络连接。 - 提供两个RGMII接口,支持更高带宽的网络连接。2. 百兆交换机功能: - 在MT7620N路由器中,集成的5端口百兆交换机负责处理局域网内的有线数据交换任务。 - 每个端口可以独立支持最高100Mbps的数据传输速率。3. IEEE802.11n标准: - IEEE802.11n是一种无线局域网通信协议,提供高速无线连接,最高传输速率可达300Mbps。 - 它允许通过MIMO(多输入多输出)技术和数据流的捆绑来提升速率和信号的可靠性。4. MIPS架构处理器: - MIPS架构是一种精简指令集计算(RISC)架构处理器,被广泛用于嵌入式系统。 - 580MHz的主频能够提供良好的性能,适用于处理路由、安全以及VoIP等高级网络应用。5. PCB与Gerber文件: - PCB是印刷电路板( Printed Circuit Board),是电子组件的物理载体。 - Gerber文件是用于PCB设计和制造的行业标准格式,包含了制作印刷电路板所需的所有相关信息。6. BOM(物料清单): - BOM是Bill of Materials的缩写,是生产过程中所需所有材料的详细清单。 - SX-LY-08A(4M+32M)BOM.xls和SX-LY-08A(8M+64M)BOM.xls代表不同配置的物料清单文件,可能涉及到不同存储容量的路由器版本。7. 烧录软件和固件: - 烧录软件用于将固件(固化的软件程序)写入路由器的存储设备中。 - 固件是运行在路由器硬件上的操作系统和程序,提供设备功能和管理界面。8. 测试报告: - 测试报告是产品经过严格测试后得出的文档,记录了产品的性能、稳定性、兼容性等测试结果。 - 通过测试报告可以评估MT7620N路由器在量产前的品质和功能标准。9. SMT贴片资料: - SMT(表面贴装技术)是电子组件安装到PCB板上的过程。 - 贴片资料包含了在SMT过程中应用的贴片技术说明、工艺参数等信息。10. QA工具: - QA工具是用于质量保证的工具,可以是软件或硬件。 - 它们用于确保产品在生产过程中的质量和符合技术规格。通过这些生产资料,可以深入理解MT7620N 5口路由器的硬件设计、制造过程和质量控制等各个方面。这些信息对于进行硬件维修、兼容性测试、固件开发等工作至关重要,能够确保路由器产品的可靠性与性能表现。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值