重新創建固定視圖
是否可以重新創建 Oracle 固定視圖?我的 GV$ACTIVE_SESSION_HISTORY 存在性能問題,可能需要重建視圖。
select * from gv$active_session_history;
由於糟糕的執行計劃,一個簡單的程序永遠執行。這僅發生在我們的少數數據庫上,並且可能與以前的 NLS 設置有關。以下執行計劃使用 2 個FIXED TABLE FULL
操作,因為NLSSORT
謂詞阻止使用固定索引:explain plan for select * from gv$active_session_history; select * from table(dbms_xplan.display); Plan hash value: 2432277601 ------------------------------------------------------------------------------------------------ | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | ------------------------------------------------------------------------------------------------ | 0 | SELECT STATEMENT | | 136K| 169M| 215 (100)| 00:00:04 | | 1 | VIEW | GV$ACTIVE_SESSION_HISTORY | 136K| 169M| 215 (100)| 00:00:04 | | 2 | NESTED LOOPS | | 136K| 62M| 215 (100)| 00:00:04 | | 3 | FIXED TABLE FULL| X$KEWASH | 136K| 3196K| 72 (100)| 00:00:02 | |* 4 | FIXED TABLE FULL| X$ASH | 1 | 454 | 0 (0)| 00:00:01 | ------------------------------------------------------------------------------------------------ Predicate Information (identified by operation id): --------------------------------------------------- 4 - filter("S"."SAMPLE_ADDR"="A"."SAMPLE_ADDR" AND "S"."SAMPLE_ID"="A"."SAMPLE_ID" AND "S"."SAMPLE_TIME"="A"."SAMPLE_TIME" AND NLSSORT("S"."NEED_AWR_SAMPLE",'nls_sort=''BINARY_CI''')=NLSSORT("A"."NEED_AWR_SAMPLE",'n ls_sort=''BINARY_CI'''))
作為比較,下面是我們 99% 的數據庫的一個很好的執行計劃:
Plan hash value: 436940376 ------------------------------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | ------------------------------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 100 | 127K| 0 (0)| 00:00:01 | | 1 | VIEW | GV$ACTIVE_SESSION_HISTORY | 100 | 127K| 0 (0)| 00:00:01 | | 2 | NESTED LOOPS | | 100 | 131K| 0 (0)| 00:00:01 | | 3 | FIXED TABLE FULL | X$KEWASH | 100 | 5200 | 0 (0)| 00:00:01 | |* 4 | FIXED TABLE FIXED INDEX| X$ASH (ind:1) | 1 | 1299 | 0 (0)| 00:00:01 | ------------------------------------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 4 - filter("S"."SAMPLE_ADDR"="A"."SAMPLE_ADDR" AND "S"."SAMPLE_ID"="A"."SAMPLE_ID" AND "S"."SAMPLE_TIME"="A"."SAMPLE_TIME" AND "S"."NEED_AWR_SAMPLE"="A"."NEED_AWR_SAMPLE")
這是我嘗試過的方法,以及不起作用的解決方法:
- 提示和計劃管理功能。 一次修復一個查詢是不夠的。這個固定視圖用在太多的系統查詢中,我不想全部修改。例如,我可以使用如下提示修復我的範例
select /*+ use_hash(@"SEL$3" "A"@"SEL$3") */ * from gv$active_session_history order by sample_time desc;
:但我無法更改使用 GV$* 的系統查詢,並且我不想管理每個單獨的查詢。- 收集統計數據。 “Rows = 1”意味著統計數據不好,但我已經嘗試收集統計數據,但沒有幫助。
- 偽造統計數據。 即使在將表行設置得非常高並且將列設置得很低之後,我也無法制定使用雜湊聯接的計劃。即使優化器認為連接返回數万億行,它仍然使用帶有兩個全表掃描的嵌套循環。
- 更改 NLS 設置。 起初,這看起來像是典型的語言排序忽略索引問題。但是 nls_sort 和 nls_comp 都設置為 BINARY。當我在會話級別更改 nls_comp 和 nls_sort 時,謂詞有 2 個 NLSSORT 函式:
alter session set nls_comp='LINGUISTIC'; alter session set nls_sort='BINARY_CI'; explain plan for select * from gv$active_session_history where sql_id = '7f7bap53hb12w'; select * from table(dbms_xplan.display); ... Predicate Information (identified by operation id): --------------------------------------------------- 4 - filter(NLSSORT("A"."SQL_ID",'nls_sort=''BINARY_CI''')=HEXTORAW('37663762617035336 86231327700') AND "S"."SAMPLE_ADDR"="A"."SAMPLE_ADDR" AND "S"."SAMPLE_ID"="A"."SAMPLE_ID" AND "S"."SAMPLE_TIME"="A"."SAMPLE_TIME" AND NLSSORT("S"."NEED_AWR_SAMPLE",'nls_sort=''BINARY_CI''')=NLSSORT("A"."NEED_AWR_SAMPLE",'n ls_sort=''BINARY_CI'''))
當我將它們設置回 BINARY 時,其中一個 NLSSORT 消失了,但一個仍然存在,從而阻止了索引:
alter session set nls_comp='BINARY'; alter session set nls_sort='BINARY'; explain plan for select * from gv$active_session_history where sql_id = '7f7bap53hb12w'; select * from table(dbms_xplan.display); ... Predicate Information (identified by operation id): --------------------------------------------------- 4 - filter("A"."SQL_ID"='7f7bap53hb12w' AND "S"."SAMPLE_ADDR"="A"."SAMPLE_ADDR" AND "S"."SAMPLE_ID"="A"."SAMPLE_ID" AND "S"."SAMPLE_TIME"="A"."SAMPLE_TIME" AND NLSSORT("S"."NEED_AWR_SAMPLE",'nls_sort=''BINARY_CI''')=NLSSORT("A"."NEED_AWR_SAMPLE",'n ls_sort=''BINARY_CI'''))
- 找到視圖源。 我找不到完整的視圖源。它不在 DBA_VIEWS 中,只有前 4000 個字元在 $FIXED_VIEW_DEFINITION 中。我在 $ORACLE_HOME/rdbms/admin/ 中嘗試過
grep -i v.*active_session_history *
,但什麼也沒看到。- 重新編譯。
alter view gv$active_session_history compile;
拋出 ORA-600。我在 Solaris 上執行 11.2.0.4。我創建了一個 Oracle 支持服務請求,但尚未收到答复。
假設您使用以下參數創建了數據庫:
NLS_COMP=LINGUISTIC NLS_SORT=BINARY_CI
我所說的創造,真正的意思是從頭開始創造。DBCA 自定義數據庫,或
CREATE DATABASE
手動執行和字典腳本。如果發生這種情況,這些將是您的數據庫級 NLS 屬性:
SQL> select * from nls_database_parameters where parameter in ('NLS_COMP', 'NLS_SORT') order by parameter; PARAMETER VALUE ---------- ---------- NLS_COMP LINGUISTIC NLS_SORT BINARY_CI
(預設情況下,您應該看到
BINARY
andBINARY
,老實說,我不記得數據庫具有不同值的單個案例 - 除了我剛剛在我的沙箱中創建的那個。)鑑於上述情況,您將獲得與您的問題相同的執行計劃。您可以重新啟動實例,或者在會話或系統(實例)級別設置
NLS_COMP
和設置NLS_SORT
相同的值,它不會“修復”執行計劃。要修改上述設置,技術上可以(但永遠不要在真實數據庫中這樣做)手動更新這些值(重新執行字典腳本不會更新):
SQL> update props$ set value$ = 'BINARY' where name in ('NLS_COMP', 'NLS_SORT'); 2 rows updated. SQL> commit; Commit complete.
在此之後(以及關閉 + 啟動),相同的查詢使用了固定索引,而過濾器中沒有任何隱式
NLSSORT
呼叫。還原更改:
SQL> update props$ set value$ = 'BINARY_CI' where name in ('NLS_SORT'); 1 row updated. SQL> update props$ set value$ = 'LINGUISTIC' where name in ('NLS_COMP'); 1 row updated. SQL> commit;
關機,開機,解釋,dbms_xplan.display,又錯了。
另一個(麻煩,但至少受支持)選項是使用預設 (
BINARY
,BINARY
) 值重新創建數據庫。