OCP认证考试指南(14):管理数据库性能(1)

1、无效的对象

Oracle总是会尝试自动重编译无效的PL/SQL对象和视图,但是可能不会成功。虽然Oracle可能建议手动地进行编译,不过我们并非必须进行这个操作。

1.1、标识无效的对象

为了标识数据库中的所有无效的对象,我们可以作为SYSTEM用户或其他有权限的用户做如下查询。

SQL> select owner, object_name, object_type 
  2  from dba_objects 
  3  where status = 'INVALID';

1.2、修正无效的对象

编译对象

SQL> alter procedure ADD_NUMS compile;
 
Procedure altered.

如果编译成功,就不存在问题,如果编译失败,就需要找出失败的原因。

SQL> show errors

如果希望确定编译错误的原因,通常需要首先使用DBA_DEPENDENCIES视图。

SQL> desc dba_dependencies;
 Name                                      Null?    Type
 ----------------------------------------- -------- ---------------
 OWNER                                     NOT NULL VARCHAR2(30)
 NAME                                      NOT NULL VARCHAR2(30)
 TYPE                                               VARCHAR2(17)
 REFERENCED_OWNER                                   VARCHAR2(30)
 REFERENCED_NAME                                    VARCHAR2(64)
 REFERENCED_TYPE                                    VARCHAR2(17)
 REFERENCED_LINK_NAME                               VARCHAR2(128)
 DEPENDENCY_TYPE                                    VARCHAR2(4)

如果要重新编译成百上千的的无效对象,可以运行下面命令。

SQL> @?/rdbms/admin/utlrp

练习一个修正无效对象的例子。

#############################################
# 建个用户,也是新建个模式
#############################################
 
SQL> grant dba to testuser identified by testuser;
 
Grant succeeded.
 
SQL> conn testuser/testuser
Connected.
 
#############################################
# 建表、建视图、建过程
#############################################
 
SQL> create table testtab(n1 number, d1 date);
 
Table created.
 
SQL> insert into testtab values (1, sysdate);
 
1 row created.
 
SQL> create or replace view v1
  2  as
  3  select d1 from testtab;
 
View created.
 
SQL> create or replace procedure p1
  2  as
  3  cnt number;
  4  begin
  5  select count(*) into cnt from testtab;
  6  end;
  7  /
 
Procedure created.
 
#############################################
# 查询对象的状态,都是VALID
# 把表删除一个列后,视图和过程的状态都为INVALID
#############################################
 
SQL> select object_name, object_type, status from user_objects;
 
OBJECT_NAME          OBJECT_TYPE         STATUS
-------------------- ------------------- -------
V1                   VIEW                VALID
TESTTAB              TABLE               VALID
P1                   PROCEDURE           VALID
 
SQL> alter table testtab drop column d1;
 
Table altered.
 
SQL> select object_name, object_type, status from user_objects;
 
OBJECT_NAME          OBJECT_TYPE         STATUS
-------------------- ------------------- -------
V1                   VIEW                INVALID
TESTTAB              TABLE               VALID
P1                   PROCEDURE           INVALID
 
#############################################
# 重新编译之后,过程可以,视图报错。因为过程没有根据名称引用列,视图是基于某个列的
#############################################
 
SQL> alter procedure p1 compile;
 
Procedure altered.
 
SQL> alter view v1 compile;
 
Warning: View altered with compilation errors.
 
#############################################
# 通过诊断,我们能发现原因
#############################################
 
SQL> select referenced_name, referenced_owner, referenced_type
  2  from user_dependencies where name = 'V1';
 
REFERENCED_NAME      REFERENCED_OWNER     REFERENCED_TYPE
-------------------- -------------------- -----------------
TESTTAB              TESTUSER             TABLE
D1                   TESTUSER             NON-EXISTENT
D1                   PUBLIC               NON-EXISTENT
 
SQL> select text from user_views where view_name = 'V1';
 
TEXT
------------------------------------------------------------------
select d1 from testtab
 
#############################################
# 将指定列添加回TESTTAB表
#############################################
 
SQL> alter table testtab add (d1 date);
 
Table altered.
 
SQL> alter view v1 compile;
 
View altered.

2、无用的索引

2.1、标识无用的索引

旧版本中执行SQL语句时,如果指定会话试图使用无用的索引,就会立即返回一条错误的消息,同时语句执行失败。如果希望10G数据库实现旧版本中无用索引导致返回错误消息的功能,可以执行以下命令。(默认为TRUE)

SQL> alter system set skip_unusable_indexes = false;

检测就得无用的索引

SQL> select owner, index_name from dba_indexes where status = 'UNUSABLE';

2.2、修正无用的索引

如果rowid不正确,索引就会标记为无用。为了修复无用索引,必须使用ALTER INDEX…REBUILD命令。索引重建过程需要额外的存储空间。

REBUILD命令语法具有多种选项,其中最重要的选项是TABLESPACE、ONLINE以及NOLOGGING。在默认情况下,索引在其当前表空间内重建,不过如果使用TABLESPACE关键字指定某个表空间,重建就会动至这个表空间内进行。同样在默认情况下,重建过程会为DML命令锁定指定的表,不过使用ONLINE关键字可以避免这种状况。NOLOGGING关键字则指示不为索引重建操作生成重做,这样能更快速完成重建。

启用NOLOGGING选项只是为索引重建禁用重做生成,在索引重建之后,针对该索引的所有DML命令都会像平时一样生成重做。

#############################################
# 用上面测试过的用户和表,创建两个索引
#############################################
 
SQL> create index n1_idx on testtab(n1);
 
Index created.
 
SQL> create index d1_idx on testtab(d1);
 
Index created.
 
#############################################
# 查看索引状态有效,之后我们移动指定的表,再查状态变成无用索引
#############################################
 
SQL> select index_name, status from user_indexes;
 
INDEX_NAME                     STATUS
------------------------------ --------
N1_IDX                         VALID
D1_IDX                         VALID
 
SQL> alter table testtab move;
 
Table altered.
 
SQL> select index_name, status from user_indexes;
 
INDEX_NAME                     STATUS
------------------------------ --------
N1_IDX                         UNUSABLE
D1_IDX                         UNUSABLE
 
#############################################
# 重建索引
#############################################
 
SQL> alter index n1_idx rebuild online nologging;
 
Index altered.
 
SQL> select index_name, status from user_indexes;
 
INDEX_NAME                     STATUS
------------------------------ --------
N1_IDX                         VALID
D1_IDX                         UNUSABLE
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值