SQL> @ver
BANNER
--------------------------------------------------------------------------------
Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 - 64bit Production
SQL> drop table t purge ;
SQL> create table t as select rownum id ,mod(rownum,100)+1 id1,mod(rownum,200)+1 id2,cast(NULL as varchar2(10)) name from dual connect by level <=2e4;
Table created.
SQL> desc t
Name Null? Type
----- -------- -------------
ID NUMBER
ID1 NUMBER
ID2 NUMBER
NAME VARCHAR2(10)
SQL> exec dbms_stats.gather_table_stats(user,'T',method_opt=>'for all columns size 1');
PL/SQL procedure successfully completed.
SQL> select table_name,pct_free,num_rows,blocks,empty_blocks,chain_cnt,avg_row_len from dba_tables where wner=user and table_name='T';
TABLE_NAME PCT_FREE NUM_ROWS BLOCKS EMPTY_BLOCKS CHAIN_CNT AVG_ROW_LEN
---------- ---------- ---------- ---------- ------------ ---------- -----------
T 10 20000 51 0 0 10
SQL> update t set name='test1test2' ;
20000 rows updated.
SQL> commit ;
Commit complete.
SQL> exec dbms_stats.gather_table_stats(user,'T',method_opt=>'for all columns size 1');
PL/SQL procedure successfully completed.
SQL> select table_name,pct_free,num_rows,blocks,empty_blocks,chain_cnt,avg_row_len from dba_tables where wner=user and table_name='T';
TABLE_NAME PCT_FREE NUM_ROWS BLOCKS EMPTY_BLOCKS CHAIN_CNT AVG_ROW_LEN
---------- ---------- ---------- ---------- ------------ ---------- -----------
T 10 20000 250 0 0 21
SQL> analyze table t compute statistics;
SQL> select table_name,pct_free,num_rows,blocks,empty_blocks,chain_cnt,avg_row_len from dba_tables where wner=user and table_name='T';
TABLE_NAME PCT_FREE NUM_ROWS BLOCKS EMPTY_BLOCKS CHAIN_CNT AVG_ROW_LEN
---------- ---------- ---------- ---------- ------------ ---------- -----------
T 10 20000 250 6 11490 28
SQL> create table t1 pctfree 5 as select rownum id ,mod(rownum,100)+1 id1,mod(rownum,200)+1 id2,cast('test1test2' as varchar2(10)) name from dual connect by level <=2e4;Table created.
SQL> SELECT a, b, COUNT (*) c
FROM (SELECT DBMS_ROWID.rowid_block_number (ROWID) a,
DBMS_ROWID.rowid_relative_fno (ROWID) b FROM t1)
GROUP BY a, b ORDER BY a;
A B C
---------- ---------- ----------
1499 4 293
1500 4 286
1501 4 289
....
1798 4 277
1799 4 279
1801 4 276
1802 4 278
1803 4 278
.....
1832 4 279
1833 4 277
1834 4 277
1835 4 278
1836 4 276
1837 4 214
71 rows selected.
SQL> select min(c),max(c),avg(c) from (
SELECT a, b, COUNT (*) c
FROM (SELECT DBMS_ROWID.rowid_block_number (ROWID) a,
DBMS_ROWID.rowid_relative_fno (ROWID) b FROM t1)
5 GROUP BY a, b ORDER BY a) where c<>214;
MIN(C) MAX(C) AVG(C)
---------- ---------- ----------
276 293 282.657143
SQL> drop table t1 purge;
Table dropped.
SQL> create table t1 pctfree 5 as select rownum id ,mod(rownum,100)+1 id1,mod(rownum,200)+1 id2,cast(NULL as varchar2(10)) name from dual connect by level <=279;
279 rows created.
SQL> ALTER TABLE t1 MINIMIZE RECORDS_PER_BLOCK ;
Table altered.
SQL> delete from t1;
279 rows deleted.
SQL> commit ;
Commit complete.
SQL> insert into t1 select rownum id ,mod(rownum,100)+1 id1,mod(rownum,200)+1 id2,cast(NULL as varchar2(10)) name from dual connect by level <=2e4;
20000 rows created.
SQL> commit ;
Commit complete.
SQL> exec dbms_stats.gather_table_stats(user,'T1',method_opt=>'for all columns size 1');
PL/SQL procedure successfully completed.
SQL> select table_name,pct_free,num_rows,blocks,empty_blocks,chain_cnt,avg_row_len from dba_tables where wner=user and table_name='T1';
TABLE_NAME PCT_FREE NUM_ROWS BLOCKS EMPTY_BLOCKS CHAIN_CNT AVG_ROW_LEN
---------- ---------- ---------- ---------- ------------ ---------- -----------
T1 5 20000 76 0 0 10
SQL> update t1 set name='test1test2' ;
20000 rows updated.
SQL> commit ;
Commit complete.
SQL> exec dbms_stats.gather_table_stats(user,'T1',method_opt=>'for all columns size 1');
PL/SQL procedure successfully completed.
SQL> select table_name,pct_free,num_rows,blocks,empty_blocks,chain_cnt,avg_row_len from dba_tables where wner=user and table_name='T1';
TABLE_NAME PCT_FREE NUM_ROWS BLOCKS EMPTY_BLOCKS CHAIN_CNT AVG_ROW_LEN
---------- ---------- ---------- ---------- ------------ ---------- -----------
T1 5 20000 76 0 0 21
SQL> analyze table t1 compute statistics;
Table analyzed.
SQL> select table_name,pct_free,num_rows,blocks,empty_blocks,chain_cnt,avg_row_len from dba_tables where wner=user and table_name='T1';
TABLE_NAME PCT_FREE NUM_ROWS BLOCKS EMPTY_BLOCKS CHAIN_CNT AVG_ROW_LEN
---------- ---------- ---------- ---------- ------------ ---------- -----------
T1 5 20000 76 4 0 25
ALTER TABLE scott.t1 NOMINIMIZE RECORDS_PER_BLOCK;
UPDATE SYS.tab$ SET spare1 = 32768+260-1
WHERE (obj#, dataobj#) IN (SELECT object_id, data_object_id FROM dba_objects WHERE wner = 'SCOTT' AND object_name = 'T1');
COMMIT ;
SQL> create bitmap index i_t1_id2 on t1(id2);
create bitmap index i_t1_id2 on t1(id2)
*
ERROR at line 1:
ORA-28604: table too fragmented to build bitmap index (16778715,264,264)
--建立b-tree索引没有问题.
SQL> create index i_t1_id1 on t1(id1);
Index created.
SQL> create index i_t1_id2 on t1(id2);
Index created.
SQL> select * from t1 where id1=42 and id2=42;
select * from t1 where id1=42 and id2=42
*
ERROR at line 1:
ORA-00600: internal error code, arguments: [qerbtRop:rowidIllegal], [], [], [], [], [], [], [], [], [], [], []
--这个就是我生产系统遇到的问题在春节前的事情,而且走这个计划非常特殊,仅仅在做年报表的时候才执行类似的执行计划.
--使用提示正常,如下
select /*+ full(t1) */* from t1 where id1=42 and id2=42;
select /*+ index(t1 ,i_t1_id1) */* from t1 where id1=42 and id2=42;
select /*+ index(t1 ,i_t1_id2) */* from t1 where id1=42 and id2=42;
--建立如下索引后也正常.
SQL> create index i_t1_id1_id2 on t1(id1,id2);
SQL> drop index i_t1_id1_id2;
SQL> explain plan for select * from t1 where id1=42 and id2=42;
Explained.
SQL> @dp
PLAN_TABLE_OUTPUT
---------------------------
Plan hash value: 2192997210
---------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
---------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 19 | 2 (0)| 00:00:01 |
| 1 | TABLE ACCESS BY INDEX ROWID | T1 | 1 | 19 | 2 (0)| 00:00:01 |
| 2 | BITMAP CONVERSION TO ROWIDS | | | | | |
| 3 | BITMAP AND | | | | | |
| 4 | BITMAP CONVERSION FROM ROWIDS| | | | | |
|* 5 | INDEX RANGE SCAN | I_T1_ID2 | | | 1 (0)| 00:00:01 |
| 6 | BITMAP CONVERSION FROM ROWIDS| | | | | |
|* 7 | INDEX RANGE SCAN | I_T1_ID1 | | | 1 (0)| 00:00:01 |
---------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
5 - access("ID2"=42) 7 - access("ID1"=42)20 rows selected.
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/267265/viewspace-763315/ ,如需转载,请注明出处,否则将追究法律责任。