表收集错误导致执行计划错误
有时候,表收集信息错误,导致执行计划错误问题。 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)
坚持,专注