是否可以重新创建 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 支持服务请求,但尚未收到答复。