表收集错误导致执行计划错误

Posted 侯志清-江西南昌

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了表收集错误导致执行计划错误相关的知识,希望对你有一定的参考价值。

有时候,表收集信息错误,导致执行计划错误问题。
SQL> insert into test values(1,user1);
已创建 1 行。
SQL> commit;
提交完成。
SQL> select * from test;
        ID NAME
---------- ----------------------------------------
         1 user1
SQL> insert into test values(2,user2);
已创建 1 行。
SQL> commit;
提交完成。
SQL> DECLARE
  2  BEGIN
  3  dbms_stats.gather_table_stats(
  4     ownname=>hzq,
  5     tabname=>test,
  6     cascade=>true
  7     );
  8  END;
  9  /
PL/SQL 过程已成功完成。
SQL> set autotrace trace explain;
SQL> select * from test where id>1;
执行计划
----------------------------------------------------------
Plan hash value: 2500689602
---------------------------------------------------------------------------------------------------
| Id  | Operation                           | Name        | Rows  | Bytes | Cost (%CPU)| Time     |
---------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                    |             |     1 |     9 |     2   (0)| 00:00:01 |
|   1 |  TABLE ACCESS BY INDEX ROWID BATCHED| TEST        |     1 |     9 |     2   (0)| 00:00:01 |
|*  2 |   INDEX RANGE SCAN                  | IDX_TEST_ID |     1 |       |     1   (0)| 00:00:01 |
---------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
   2 - access("ID">1)
SQL> begin
  2  for i in  1..100000 loop
  3  insert into test values(i,user||i);
  4  commit;
  5  end loop;
  6  end;
  7  /
PL/SQL 过程已成功完成。
--插入10万行数据之后,执行计划本应该走全表扫描,但是还是走了索引范围扫描
SQL> select * from test where id>1;
执行计划
----------------------------------------------------------
Plan hash value: 2500689602
---------------------------------------------------------------------------------------------------
| Id  | Operation                           | Name        | Rows  | Bytes | Cost (%CPU)| Time     |
---------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                    |             |     1 |     9 |     2   (0)| 00:00:01 |
|   1 |  TABLE ACCESS BY INDEX ROWID BATCHED| TEST        |     1 |     9 |     2   (0)| 00:00:01 |
|*  2 |   INDEX RANGE SCAN                  | IDX_TEST_ID |     1 |       |     1   (0)| 00:00:01 |
---------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
   2 - access("ID">1)
--重新收集之后,索引计划会纠正。
SQL> DECLARE
  2  BEGIN
  3  dbms_stats.gather_table_stats(
  4     ownname=>hzq,
  5     tabname=>test,
  6     cascade=>true
  7     );
  8  END;
  9  /
PL/SQL 过程已成功完成。
SQL> select * from test where id>1;
执行计划
----------------------------------------------------------
Plan hash value: 1357081020
--------------------------------------------------------------------------
| Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |      |   100K|  1464K|   103   (1)| 00:00:01 |
|*  1 |  TABLE ACCESS FULL| TEST |   100K|  1464K|   103   (1)| 00:00:01 |
--------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
   1 - filter("ID">1)

 

以上是关于表收集错误导致执行计划错误的主要内容,如果未能解决你的问题,请参考以下文章

检查已终止。收集事实数据时检测到错误

oracle选择了错误的执行计划,怎么办

MO拆分计划行程序中写入PRODUCTIONORDERS表数据出现重复导致报错(BUG)20180502

oracle中的统计信息问题

MySQL 统计信息不准导致的性能问题

在包内多次运行收集表统计信息会导致性能问题