续《表扫描与索引扫描返回的行数不一致》

简介: 续《表扫描与索引扫描返回的行数不一致》上篇文章主要介绍了如何从分析表得到的报错,以及trace中的信息,判断表返回的记录与索引返回记录不一致时的处理方式。

续《表扫描与索引扫描返回的行数不一致


上篇文章主要介绍了如何从分析表得到的报错,以及trace中的信息,判断表返回的记录与索引返回记录不一致时的处理方式。下面这篇文章则介绍了针对ORA-1499进行问题排查的一些基本方法。


OERR: ORA-1499 table/Index Cross Reference Failure - see trace file (文档 ID 1499.1)


Error: ORA 1499
Text: table/Index Cross Reference Failure - see trace file
-------------------------------------------------------------------------------
Cause:  An error occurred when validating an index or a table using the
        ANALYZE command.
        One or more entries does not point to the appropriate cross-reference.
Action: Check the trace file for more descriptive messages about the problem.
        Correct these errors.


ORA-1499的错误是通过“"ANALIZE TABLE|CLUSTER <name> VALIDATE STRUCTURE CASCADE”分析得出的,它的含义是表或聚类和索引之间存在不一致性,具体来讲是索引键值未出现在索引中,或者相反。


trace文件中包含:

<description>: tsn: <tablespace number> rdba: <relative dba>

description有以下值:

"row not found in index" 
"Table/Index row count mismatch"
"row mismatch in index dba"
"Table row count/Bitmap index bit count mismatch"
"kdavls: kdcchk returns %d when checking cluster dba 0x%08lx objn %d\n"

tsn:    Tablespace Number表示的是索引存储的表空间编号。

rdba: 是索引段头相对于数据块的存储地址。


SQL> analyze table DEPT validate structure cascade;
analyze table case7 validate structure cascade
*
ERROR at line 1:
ORA-01499: table/index cross reference failure - see trace file


trace文件的实例:

row not found in index tsn: 5 rdba: 0x02c00061


哪些索引受影响?
包含ORA-1499的trace文件提供了与索引相关的段头rdba。查询dba_segments来明确索引:
SELECT owner, segment_name, segment_type, partition_name
FROM   DBA_SEGMENTS
WHERE  header_file = (SELECT file#
                                          FROM   v$datafile
                                          WHERE  rfile# = dbms_utility.data_block_address_file(to_number('&rdba','XXXXXXXX'))
                                          AND  ts#= &tsn)
                 AND header_block = dbms_utility.data_block_address_block(to_number('&rdba','XXXXXXXX'));
&rdba值应该是删除’0x‘的十六进制的rdba,tsn是表空间编号。
例如:
SELECT owner, segment_name, segment_type, partition_name
FROM DBA_SEGMENTS
WHERE header_file = (SELECT file#
                                         FROM   v$datafile
                                     WHERE  rfile# = dbms_utility.data_block_address_file(to_number('02c00061','XXXXXXXX'))
                                        AND  ts#= 5)
                AND header_block = dbms_utility.data_block_address_block(to_number('02c00061','XXXXXXXX'));

明确受影响的键值
如果需要明确所有受影响的键,需要运行一次全表扫描和索引扫描:
在表中但未在索引的行:
SELECT /*+ FULL(t1) */ rowid, <indexed column list>
FROM   <Table name> t1
MINUS
SELECT /*+ index(t <Index name>) */ rowid, <indexed column list>
FROM   <Table name> t;

在索引中但未在表中的行:
SELECT /*+ index(t <Index name>) */ rowid, <indexed column list>
FROM   <Table name> t
MINUS
SELECT /*+ FULL(t1) */ rowid, <indexed column list>
FROM  <Table name> t1;

实例:
表名 = DEPT,索引名 = I_DEPT1,在索引I_DEPT1中的索引列:DEPTNO,DNAME.
SELECT /*+ FULL(t1) */ rowid, deptno, dname
FROM   dept t1
MINUS
SELECT /*+ index(t I_DEPT1) */ rowid, deptno, dname
FROM   dept t;

确保查询语句的执行计划使用受影响的索引,例如I_DEPT1会展示在执行计划中。查询未使用索引的原因之一是因为索引列定义为允许NULL值。如果是这样,可以添加一个where子句,例如:where deptno is not null。

导致这种问题的根本原因就是表和索引之间的不一致,可能是由于Oracle的defect产生,或者Oracle外部问题,例如IO丢失。硬件或OS子系统问题可能导致IO丢失写入。如果出现IO丢失,包含表或索引的块修改操作就可能不会写入Oracle的数据文件中,引起键缺失。解决方法可以参考上一篇文章《表扫描与索引扫描返回的行数不一致》。当出现表和索引之间不一致的情况,即表中的行不在索引中,删除并重建索引是常用的一种合适方法。
目录
相关文章
|
6月前
|
存储 关系型数据库 索引
10. 在一个非主键字段上创建了索引, 想要根据该字段查询到数据, 需要查询几次 ?
在非主键字段上创建索引,查询数据通常需两次。对于MyISAM,先通过索引找到数据行指针,再获取数据;而InnoDB则先找主键ID,再从主键索引中查找数据。
39 0
|
1月前
|
SQL 数据库
SQL查询中排除空值列的技巧与方法
在数据库查询中,经常需要处理包含空值(NULL)的数据列
|
3月前
|
SQL 移动开发 Oracle
SQL查询连续六天数据记录的技巧与方法
在数据库查询中,实现针对连续几天(如连续六天)的数据筛选是一个常见且稍具挑战性的任务
|
5月前
|
SQL 关系型数据库 MySQL
MySQL数据库——索引(5)-索引使用(上),验证索引效率、最左前缀法则、范围查询、索引失效情况、SQL提示
MySQL数据库——索引(5)-索引使用(上),验证索引效率、最左前缀法则、范围查询、索引失效情况、SQL提示
71 0
|
SQL 关系型数据库 MySQL
这个大表走索引字段查询的 SQL 怎么就成全扫描了
这个大表走索引字段查询的 SQL 怎么就成全扫描了
这个大表走索引字段查询的 SQL 怎么就成全扫描了
|
索引 关系型数据库 Oracle
[20170210]索引范围扫描3.txt
[20170210]索引范围扫描3.txt --昨天写了一篇索引范围扫描文章,链接:http://blog.itpub.net/267265/viewspace-2133289/ --才想起来我以前理解的一个错误,链接:http://blog.
828 0
|
SQL
【记录】T-SQL 分组排序中取出最新数据
原文:【记录】T-SQL 分组排序中取出最新数据 示例 Product 表结构: 示例 Product 表数据: 想要的效果是,以 GroupName 字段分组,取出分组中通过 Sort 降序最新的数据,通过示例数据,可以推算出结果数据的 ID 应该为:7、5、3。
775 0