问题描述
嗨,团队,
我正在尝试创建测试场景,其中使用1列ID创建表名测试。
测试表中的值:
我的查询是当试图触发下面的语句:
我在一个计划中看到,索引全扫描正在发生。我们已经收集了ID的直方图,我们仍然看到索引全扫描
我的问题是,如果我试图选择整个表,如在where子句: 其中id为null,如果这去FTS,我可以理解。
但是,如果我的where子句的where id不为null,则不应进入索引全扫描,尤其是当我有直方图时
请您在此处进行指导,并让我们了解更多信息
问候,
克里希纳
我正在尝试创建测试场景,其中使用1列ID创建表名测试。
Name Null? Type ----------------------------------------------------------------------------------------------------------------- -------- ---------------------------------------------------------------------------- ID NUMBER
测试表中的值:
SQL> select count(*) ,id from test group by id;
COUNT(*) ID
---------- ----------
9 1
99991我的查询是当试图触发下面的语句:
select count(*) from Test where id is not null ;
我在一个计划中看到,索引全扫描正在发生。我们已经收集了ID的直方图,我们仍然看到索引全扫描
我的问题是,如果我试图选择整个表,如在where子句: 其中id为null,如果这去FTS,我可以理解。
但是,如果我的where子句的where id不为null,则不应进入索引全扫描,尤其是当我有直方图时
select /* 002 */ count(*) from test where id is not null
Plan hash value: 3822811674
----------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | | | 1 (100)| |
| 1 | SORT AGGREGATE | | 1 | 1 | | |
|* 2 | INDEX FULL SCAN| AMRIT_1 | 9 | 9 | 1 (0)| 00:00:01 |
----------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - filter("ID" IS NOT NULL)请您在此处进行指导,并让我们了解更多信息
问候,
克里希纳
专家解答
it should not go in index full scan
你想要数据库做什么?全面扫描表?为什么?为什么有直方图会有什么不同?
要记住的关键是索引通常在物理上小于它所在的表。
因此,完全扫描索引读取的数据少于完全扫描表。
因此,阅读索引应该更快。
在这种情况下,索引比表小得多。因为Oracle数据库从BTrees中排除空条目。所以要读取的数据少了很多!
使用char(1000) 列重新创建示例以使行 “大”。
使用索引和表时,请密切注意缓冲区列:
缓冲区 => 逻辑I/O操作
所以
全索引扫描 = 6 I/Os
全表扫描 = 191 I/Os
所以 reading the table is orders of magnitude more work than reading the index!
所以, why do you NOT want to read the index again?
你想要数据库做什么?全面扫描表?为什么?为什么有直方图会有什么不同?
要记住的关键是索引通常在物理上小于它所在的表。
因此,完全扫描索引读取的数据少于完全扫描表。
因此,阅读索引应该更快。
在这种情况下,索引比表小得多。因为Oracle数据库从BTrees中排除空条目。所以要读取的数据少了很多!
使用char(1000) 列重新创建示例以使行 “大”。
使用索引和表时,请密切注意缓冲区列:
create table t ( c1 char(1000) ); insert into t with rws as ( select level x from dual connect by level <= 100000 ) select case when x < 10 then x end from rws; create index i on t ( c1 ); alter session set statistics_level = all; cl scr select count(*) from t where c1 is not null ; select * from table(dbms_xplan.display_cursor(null, null, 'ALLSTATS LAST')); ---------------------------------------------------------------------------------------- | Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers | ---------------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | | 1 |00:00:00.01 | 6 | | 1 | SORT AGGREGATE | | 1 | 1 | 1 |00:00:00.01 | 6 | |* 2 | INDEX FAST FULL SCAN| I | 1 | 8 | 9 |00:00:00.01 | 6 | ---------------------------------------------------------------------------------------- select /*+ full ( t ) */count(*) from t where c1 is not null ; select * from table(dbms_xplan.display_cursor(null, null, 'ALLSTATS LAST')); ------------------------------------------------------------------------------------- | Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers | ------------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | | 1 |00:00:00.01 | 191 | | 1 | SORT AGGREGATE | | 1 | 1 | 1 |00:00:00.01 | 191 | |* 2 | TABLE ACCESS FULL| T | 1 | 8 | 9 |00:00:00.01 | 191 | -------------------------------------------------------------------------------------
缓冲区 => 逻辑I/O操作
所以
全索引扫描 = 6 I/Os
全表扫描 = 191 I/Os
所以 reading the table is orders of magnitude more work than reading the index!
所以, why do you NOT want to read the index again?
文章转载自ASKTOM,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。




