於節點2上發現一個sql,其結構如下:
select distinct t.attr, t.item
from a t
where attr = :1
and (pro = :2 or exists
(select 1
from b hps
where hps.pro = :3
and t.pro = hps.sub_pro))
鑑於以往的經驗,一開始就覺得子查詢中的連接謂詞or有問題。
注:
表a有50多萬條記錄,attr和pro上分別有索引;表b有10萬條記錄,pro上有單獨索引,同時(pro,sub_pro)組成unique索引;
同時表a上的attr,pro字段的分佈情況如下,對於表a,pro字段的選擇性比attr高出了很多
SQL> select count(distinct pro),count(distinct attr) from a;
COUNT(DISTINCT pro) COUNT(DISTINCT attr)
------------------------- ---------------------------
164067 716
先通過set autotrace traceonly查看一把其執行計劃和consistent gets
--------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 63 | 945 | 83 (2)| 00:00:01 |
| 1 | HASH UNIQUE | | 63 | 945 | 83 (2)| 00:00:01 |
|* 2 | FILTER | | | | | |
| 3 | TABLE ACCESS BY INDEX ROWID| a | 1268 | 19020 | 82 (0)| 00:00:01 |
|* 4 | INDEX RANGE SCAN | idx_a_attr | 1268 | | 8 (0)| 00:00:01 |
|* 5 | INDEX UNIQUE SCAN | idx_b_un_pro_sub | 1 | 12 | 1 (0)| 00:00:01 |
--------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - filter("pro"=TO_NUMBER(:B) OR EXISTS (SELECT 0 FROM "b" "HPS" WHERE
"HPS"."SUB_pro"=:B1 AND "HPS"."pro"=TO_NUMBER(:C)))
4 - access("attr"=TO_NUMBER(:A))
5 - access("HPS"."pro"=TO_NUMBER(:C) AND "HPS"."SUB_pro"=:B1)
Statistics
----------------------------------------------------------
0 recursive calls
0 db block gets
4690 consistent gets
0 physical reads
0 redo size
589 bytes sent via SQL*Net to client
487 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
1 rows processed
從執行計劃看出,訪問表a的時候選擇了attr上的索引,實際效果不佳,邏輯讀有4690;
通過等價改寫後的sql如下,去除了謂詞or,改用了union
select distinct t.attr, t.item
from a t
where attr = :a
and pro = :b
union
select distinct t.attr, t.item
from a t
where attr = :a
and exists
(select 1
from b hps
where hps.pro = :c
and t.pro = hps.sub_pro)
改寫後的sql的執行計劃如下
--------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 6 | 150 | 16 (75)| 00:00:01 |
| 1 | SORT UNIQUE | | 6 | 150 | 16 (75)| 00:00:01 |
| 2 | UNION-ALL | | | | | |
|* 3 | TABLE ACCESS BY INDEX ROWID| a | 1 | 15 | 4 (0)| 00:00:01 |
|* 4 | INDEX RANGE SCAN | idx_a_pro | 3 | | 3 (0)| 00:00:01 |
|* 5 | TABLE ACCESS BY INDEX ROWID| a | 1 | 15 | 3 (0)| 00:00:01 |
| 6 | NESTED LOOPS | | 5 | 135 | 10 (10)| 00:00:01 |
| 7 | SORT UNIQUE | | 5 | 60 | 2 (0)| 00:00:01 |
|* 8 | INDEX RANGE SCAN | idx_b_un_pro_sub | 5 | 60 | 2 (0)| 00:00:01 |
|* 9 | INDEX RANGE SCAN | idx_a_pro | 3 | | 2 (0)| 00:00:01 |
--------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
3 - filter("attr"=TO_NUMBER(:A))
4 - access("pro"=TO_NUMBER(:B))
5 - filter("attr"=TO_NUMBER(:A))
8 - access("HPS"."pro"=TO_NUMBER(:C))
9 - access("T"."pro"="HPS"."SUB_pro")
Statistics
----------------------------------------------------------
0 recursive calls
0 db block gets
24 consistent gets
0 physical reads
0 redo size
589 bytes sent via SQL*Net to client
487 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
2 sorts (memory)
0 sorts (disk)
1 rows processed
訪問表a時選擇了pro上的索引,雖然增加了一次訪問次數,但是邏輯讀卻下降到了24.
優化擁有謂詞or的子查詢
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章
Linux基本操作命令
wbzjacky
2019-02-24 13:12:38
真實的模擬***綜合實驗
wbzjacky
2019-02-24 13:12:37
三層交換機的HSRP、vlan、端口聚合
wbzjacky
2019-02-24 13:12:37
HSRP和二層交換機的端口聚合、vlan
wbzjacky
2019-02-24 13:12:37
如果同事暗中傷害你,應該怎麼辦?
這個饅頭有餡
2019-02-24 13:59:08
職場中,抱怨越多的員工,越被領導瞧不起!
這個饅頭有餡
2019-02-24 13:59:08
老程序員被裁,應屆生卻能月薪 1.3 萬?這你能忍?
前端高達
2019-02-24 13:48:04
遇到到處蹭吃卻從不請客吃飯的主怎麼辦?
樑軍年
2019-02-24 13:26:35
高標準機房綜合配線安裝
wbzjacky
2019-02-24 13:12:38
IPsec ***實驗
wbzjacky
2019-02-24 13:12:37
CISCO路由AAA的Easy ***
wbzjacky
2019-02-24 13:12:37
CISCO訪問控制列表 企業網絡管理的必殺技
wbzjacky
2019-02-24 13:12:37