AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / dba / 问题 / 118478
Accepted
Jon Heller
Jon Heller
Asked: 2015-10-20 07:57:00 +0800 CST2015-10-20 07:57:00 +0800 CST 2015-10-20 07:57:00 +0800 CST

重新创建固定视图

  • 772

是否可以重新创建 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")

这是我尝试过的方法,以及不起作用的解决方法:

  1. 提示和计划管理功能。 一次修复一个查询是不够的。这个固定视图在太多的系统查询中使用,我不想全部修改。例如,我可以用这样的提示修复我的示例:select /*+ use_hash(@"SEL$3" "A"@"SEL$3") */ * from gv$active_session_history order by sample_time desc;。但我无法更改使用 GV$* 的系统查询,而且我不想管理每个单独的查询。
  2. 收集统计数据。 “Rows = 1”表示统计数据不佳,但我已经尝试收集统计数据但无济于事。
  3. 伪造统计数据。 即使在将表行设置得高得离谱并将列设置得非常低之后,我也无法计划使用散列连接。即使优化器认为连接返回千万亿行,它仍然使用带有两次全表扫描的嵌套循环。
  4. 更改 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'''))
    
  5. 找到视图源。 我找不到完整的视图源。它不在 DBA_VIEWS 中,只有前 4000 个字符在 $FIXED_VIEW_DEFINITION 中。我在 $ORACLE_HOME/rdbms/admin/ 中尝试过grep -i v.*active_session_history *,但没有看到任何东西。

  6. 重新编译。 alter view gv$active_session_history compile;抛出 ORA-600。

我在 Solaris 上运行 11.2.0.4。我创建了 Oracle 支持服务请求,但尚未收到答复。

oracle oracle-11g-r2
  • 1 1 个回答
  • 642 Views

1 个回答

  • Voted
  1. Best Answer
    Balazs Papp
    2015-10-23T04:06:59+08:002015-10-23T04:06:59+08:00

    假设您使用以下参数创建了数据库:

    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和BINARY,老实说,我不记得数据库有不同值的单一情况 - 除了我刚刚在我的沙箱中创建的那个。)

    鉴于上述情况,您将获得与问题中相同的执行计划。您可以重新启动实例,或者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) 值重新创建数据库。

    • 3

相关问题

  • Oracle 中的数据库备份 - 导出数据库还是使用其他工具?

  • ORDER BY 使用文本列的自定义优先级

  • 舒服的sqlplus界面?[关闭]

  • 如何在数据库中找到最新的 SQL 语句?

  • 如何使用正则表达式查询名称?

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    连接到 PostgreSQL 服务器:致命:主机没有 pg_hba.conf 条目

    • 12 个回答
  • Marko Smith

    如何让sqlplus的输出出现在一行中?

    • 3 个回答
  • Marko Smith

    选择具有最大日期或最晚日期的日期

    • 3 个回答
  • Marko Smith

    如何列出 PostgreSQL 中的所有模式?

    • 4 个回答
  • Marko Smith

    列出指定表的所有列

    • 5 个回答
  • Marko Smith

    如何在不修改我自己的 tnsnames.ora 的情况下使用 sqlplus 连接到位于另一台主机上的 Oracle 数据库

    • 4 个回答
  • Marko Smith

    你如何mysqldump特定的表?

    • 4 个回答
  • Marko Smith

    使用 psql 列出数据库权限

    • 10 个回答
  • Marko Smith

    如何从 PostgreSQL 中的选择查询中将值插入表中?

    • 4 个回答
  • Marko Smith

    如何使用 psql 列出所有数据库和表?

    • 7 个回答
  • Martin Hope
    Jin 连接到 PostgreSQL 服务器:致命:主机没有 pg_hba.conf 条目 2014-12-02 02:54:58 +0800 CST
  • Martin Hope
    Stéphane 如何列出 PostgreSQL 中的所有模式? 2013-04-16 11:19:16 +0800 CST
  • Martin Hope
    Mike Walsh 为什么事务日志不断增长或空间不足? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland 列出指定表的所有列 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney MySQL 能否合理地对数十亿行执行查询? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx 如何监控大型 .sql 文件的导入进度? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison 你如何mysqldump特定的表? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 对 SQL 查询进行计时? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas 如何从 PostgreSQL 中的选择查询中将值插入表中? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 列出所有数据库和表? 2011-02-18 00:45:49 +0800 CST

热门标签

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve