我们的一位数据库管理员说,在更改 Oracle 中的系统日期后(我们需要这样做以测试我们的软件)我们需要收集表的所有统计信息 - 这是真的吗?如果是,那为什么?我无法在 Oracle 文档中找到任何内容。我想到的一件事是,自动收集统计信息的工作可能会挂起,等待下一次运行日期被取消。
还有其他想法吗?
最佳答案
更改系统日期可能不需要重新收集统计信息。表统计信息不包含实际的 SYSDATE。即使执行计划对 SYSDATE 极其敏感,Oracle 似乎也能很好地处理日期更改。
但是,如果在某个地方出现与更改日期相关的奇怪错误,我也不会感到太惊讶。但是您应该向 DBA 询问具体细节,包括 Oracle 支持错误号。
下面是优化器完美处理操作系统日期更改的示例。
1:删除所有当前缓存的 SQL,以防万一。
alter system flush shared_pool;
2:创建一个带有倾斜列的表。今天有很多值(value)观,但明天只有少数值(value)观。
drop table test1;
create table test1(a date, b varchar2(100));
create index test1_idx on test1(a);
insert into test1 select trunc(sysdate), 'common value' from dual
connect by level <= 100000;
insert into test1 select trunc(sysdate)+1, 'rare value' from dual
connect by level <= 10;
--Workload to generate histograms.
select max(b) from test1 where a = trunc(sysdate);
begin
dbms_stats.gather_table_stats(user, 'TEST1');
end;
/
3:选取常用数据,从今天开始,正确使用全表扫描。
select to_char(sysdate, 'YYYY-MM-DD') current_date from dual;
CURRENT_DATE
------------
2014-01-05
explain plan for select b from test1 where a = trunc(sysdate);
select * from table(dbms_xplan.display(format => '-cost -bytes -predicate'));
Plan hash value: 4122059633
------------------------------------------------------
| Id | Operation | Name | Rows | Time |
------------------------------------------------------
| 0 | SELECT STATEMENT | | 100K| 00:00:01 |
| 1 | TABLE ACCESS FULL| TEST1 | 100K| 00:00:01 |
------------------------------------------------------
4:选择稀有数据,从明天开始,正确使用索引范围扫描。
explain plan for select b from test1 where a = trunc(sysdate)+1;
select * from table(dbms_xplan.display(format => '-cost -bytes -predicate'));
Plan hash value: 1226949
----------------------------------------------------------------------------
| Id | Operation | Name | Rows | Time |
----------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 10 | 00:00:01 |
| 1 | TABLE ACCESS BY INDEX ROWID BATCHED| TEST1 | 10 | 00:00:01 |
| 2 | INDEX RANGE SCAN | TEST1_IDX | 10 | 00:00:01 |
----------------------------------------------------------------------------
5:将操作系统时钟更改为明天。 SYSDATE 立即更新。
select to_char(sysdate, 'YYYY-MM-DD') current_date from dual;
CURRENT_DATE
------------
2014-01-06
6: 重新运行第 3 步。该查询之前返回了大量数据,现在只返回少量数据。该计划应该并且确实从全表扫描更改为索引范围扫描。
explain plan for select b from test1 where a = trunc(sysdate);
select * from table(dbms_xplan.display(format => '-cost -bytes -predicate'));
Plan hash value: 1226949
----------------------------------------------------------------------------
| Id | Operation | Name | Rows | Time |
----------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 10 | 00:00:01 |
| 1 | TABLE ACCESS BY INDEX ROWID BATCHED| TEST1 | 10 | 00:00:01 |
| 2 | INDEX RANGE SCAN | TEST1_IDX | 10 | 00:00:01 |
----------------------------------------------------------------------------
关于database - SYSDATE 更改会影响 Oracle 中的表统计信息吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20908958/