共計 7032 個字符,預計需要花費 18 分鐘才能閱讀完成。
本篇內容主要講解“ACS 與 PL/SQL 的工作情況分析”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓丸趣 TV 小編來帶大家學習“ACS 與 PL/SQL 的工作情況分析”吧!
ACS 與 PL/SQL
我們來看下 ACS 在 PL/SQL 里的工作情況,結果可能會令你非常失望。
首先構造一個 PL/SQL,里面使用到了我們在本章中創建的表 T:
SQL var sql_id varchar2(255)
SQL alter system flush shared_pool;
System altered.
SQL declare
2 x integer;
3 n number;
4 begin
5 for i in 1..10 loop
6 if i = 1 then
7 x := 500000;
8 else
9 x := 1;
10 end if;
11 select count(object_id) into n from t where id x;
12 end loop;
13 end;
14 /
PL/SQL procedure successfully completed.
這段 PL/SQL 首先會執行‘select count(object_id) into n from t where id 100000 ’1 次,然后會執行‘select count(object_id) into n from t where id 1’ 9 次,執行完成后,我們來看看是否會使用到 ACS。
SQL select
2 sql_id
3 , child_number
4 , executions
5 , parse_calls
6 , buffer_gets
7 , is_bind_sensitive
8 , is_bind_aware
9 from
10 v$sql
11 where
12 sql_id = gp03v5aw085v3
SQL_ID CHILD_NUMBER EXECUTIONS PARSE_CALLS BUFFER_GETS IS IS
————— ———— ———- ———– ———– — —
gp03v5aw085v3 0 10 1 646875 Y N
非常可惜,這個 SQL 并沒有產生多個子游標,雖然已經識別到這個 SQL 為綁定敏感 is_bind_sensitive= Y,但是 is_bind_aware= N。
SQL SELECT hash_value, sql_id, child_number, bucket_id, COUNT
2 FROM v$sql_cs_histogram
3 WHERE sql_id= gp03v5aw085v3
4 ORDER BY sql_id, child_number;
HASH_VALUE SQL_ID CHILD_NUMBER BUCKET_ID COUNT
———- ————— ———— ———- ———-
3087275875 gp03v5aw085v3 0 0 1
3087275875 gp03v5aw085v3 0 2 9
3087275875 gp03v5aw085v3 0 1 0
雖然 v$sql_cs_histogram 已經監控到了處理行數的巨大改變,但是卻沒有生成新的游標。
SQL select * from table(dbms_xplan.display_cursor(:sql_id,null, +PEEKED_BINDS
PLAN_TABLE_OUTPUT
—————————————————————————————-
SQL_ID gp03v5aw085v3, child number 0
————————————-
SELECT COUNT(OBJECT_ID) FROM T WHERE ID :B1
Plan hash value: 3694077449
————————————————————————————-
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
————————————————————————————-
| 0 | SELECT STATEMENT | | | | 4 (100)| |
| 1 | SORT AGGREGATE | | 1 | 10 | | |
| 2 | TABLE ACCESS BY INDEX ROWID| T | 1 | 10 | 4 (0)| 00:00:01 |
|* 3 | INDEX RANGE SCAN | I | 1 | | 3 (0)| 00:00:01 |
————————————————————————————-
Peeked Binds (identified by position):
————————————–
1 – :B1 (NUMBER): 5000000
Predicate Information (identified by operation id):
—————————————————
3 – access(ID :B1)
執行計劃一直沿用的是第一次產生的執行計劃,根據 Peeked Binds (identified by position): 的值為 5000000 可以推斷出來。我們嘗試在 SQL 里增加 bind_aware hint 看看,這個 hint 的作用在本章的最佳實踐小節中介紹,這里不再贅述。
SQL declare
2 x integer;
3 n number;
4 begin
5 for i in 1..10 loop
6 if i = 1 then
7 x := 5000000;
8 else
9 x := 1;
10 end if;
11 select /*+ bind_aware */count(object_id) into n from t where id x;
12 end loop;
13 end;
14 /
PL/SQL procedure successfully completed.
SQL select
2 sql_id
3 , child_number
4 , executions
5 , parse_calls
6 , buffer_gets
7 , is_bind_sensitive
8 , is_bind_aware
9 from
10 v$sql
11 where
12 sql_id = 5542a2rzny69v
SQL_ID CHILD_NUMBER EXECUTIONS PARSE_CALLS BUFFER_GETS IS IS
————— ———— ———- ———– ———– — —
5542a2rzny69v 0 10 1 687396 Y Y
雖然優化器已經標記這個游標 is_bind_aware= Y 了,但是依然沒有新的游標產生出來。在 MOS 上查找類似的問題,會發現一個 BUG:
Bug 8357294 : ADAPTIVE cursor SHARING DOESN T WORK FOR STATIC SQL cursorS FROM PL/SQL
標題的意思是由于 BUG,ACS 不能工作在 PL/SQL 的靜態游標里。但是根據測試動態游標也不能工作。
SQL declare
2 x integer;
3 n number;
4 begin
5 for i in 1..10 loop
6 if i = 1 then
7 x := 5000000;
8 else
9 x := 1;
10 end if;
11 execute immediate
12 select count(object_id) from t where id :x into n using x;
13 end loop;
14 end;
15 /
PL/SQL procedure successfully completed.
SQL select
2 sql_id
3 , child_number
4 , executions
5 , parse_calls
6 , buffer_gets
7 , is_bind_sensitive
8 , is_bind_aware
9 from
10 v$sql
11 where
12 sql_id = 6qwg6gauwbpm8
SQL_ID CHILD_NUMBER EXECUTIONS PARSE_CALLS BUFFER_GETS IS IS
————— ———— ———- ———– ———– — —
6qwg6gauwbpm8 0 10 1 687580 Y N
文中提到了 Session_Cached_Cursors 在設置為 0 后,ACS 就可以正常工作了,經過試驗也如它所說。
SQL alter session set Session_Cached_Cursors=0;
Session altered.
SQL alter system flush shared_pool;
System altered.
SQL declare
2 x integer;
3 n number;
4 begin
5 for i in 1..10 loop
6 if i = 1 then
7 x := 5000000;
8 else
9 x := 1;
10 end if;
11 select count(object_id) into n from t where id x;
12 end loop;
13 end;
14 /
PL/SQL procedure successfully completed.
SQL select
2 sql_id
3 , child_number
4 , executions
5 , parse_calls
6 , buffer_gets
7 , is_bind_sensitive
8 , is_bind_aware
9 from
10 v$sql
11 where
12 sql_id = gp03v5aw085v3
SQL_ID CHILD_NUMBER EXECUTIONS PARSE_CALLS BUFFER_GETS IS IS
————— ———— ———- ———– ———– — —
gp03v5aw085v3 0 2 3 76405 Y N
gp03v5aw085v3 1 8 7 517480 Y Y
SQL select * from table(dbms_xplan.display_cursor( gp03v5aw085v3 ,null));
PLAN_TABLE_OUTPUT
——————————————————————————————-
SQL_ID gp03v5aw085v3, child number 0
————————————-
SELECT COUNT(OBJECT_ID) FROM T WHERE ID :B1
Plan hash value: 3694077449
————————————————————————————-
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
————————————————————————————-
| 0 | SELECT STATEMENT | | | | 4 (100)| |
| 1 | SORT AGGREGATE | | 1 | 10 | | |
| 2 | TABLE ACCESS BY INDEX ROWID| T | 1 | 10 | 4 (0)| 00:00:01 |
|* 3 | INDEX RANGE SCAN | I | 1 | | 3 (0)| 00:00:01 |
————————————————————————————-
Predicate Information (identified by operation id):
—————————————————
3 – access(ID :B1)
SQL_ID gp03v5aw085v3, child number 1
————————————-
SELECT COUNT(OBJECT_ID) FROM T WHERE ID :B1
Plan hash value: 2966233522
—————————————————————————
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
—————————————————————————
| 0 | SELECT STATEMENT | | | | 14373 (100)| |
| 1 | SORT AGGREGATE | | 1 | 10 | | |
|* 2 | TABLE ACCESS FULL| T | 4999K| 47M| 14373 (2)| 00:02:53 |
—————————————————————————
Predicate Information (identified by operation id):
—————————————————
2 – filter(ID :B1)
可以看到 ACS 已經工作了,在 v$sql_cs_histogram 里也為新游標產生了新的行。
SQL SELECT hash_value, sql_id, child_number, bucket_id, COUNT
2 FROM v$sql_cs_histogram
3 WHERE sql_id= gp03v5aw085v3
4 ORDER BY sql_id, child_number;
HASH_VALUE SQL_ID CHILD_NUMBER BUCKET_ID COUNT
———- ————— ———— ———- ———-
3087275875 gp03v5aw085v3 0 1 0
3087275875 gp03v5aw085v3 0 0 1
3087275875 gp03v5aw085v3 0 2 1
3087275875 gp03v5aw085v3 1 1 0
3087275875 gp03v5aw085v3 1 0 0
3087275875 gp03v5aw085v3 1 2 8
到此,相信大家對“ACS 與 PL/SQL 的工作情況分析”有了更深的了解,不妨來實際操作一番吧!這里是丸趣 TV 網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!