Database SYSDATE更改是否会影响Oracle中的表统计信息?

Database SYSDATE更改是否会影响Oracle中的表统计信息?,database,oracle,oracle11g,database-administration,Database,Oracle,Oracle11g,Database Administration,我们的一位DBA说,在Oracle中更改系统日期后(我们需要这样做以测试我们的软件),我们需要收集表的所有统计数据-这是真的吗?如果是,为什么?我在Oracle文档中找不到任何东西。我想到的一件事是,自动收集统计数据的工作可能会挂在等待下一个跳出的运行日期 还有其他想法吗?更改系统日期可能不需要重新收集统计信息。表统计信息不包含实际的SYSDATE。即使执行计划对系统日期非常敏感,Oracle似乎也能很好地处理日期更改 然而,如果在某个地方发生了与更改日期有关的奇怪错误,我也不会感到太惊讶。但是

我们的一位DBA说,在Oracle中更改系统日期后(我们需要这样做以测试我们的软件),我们需要收集表的所有统计数据-这是真的吗?如果是,为什么?我在Oracle文档中找不到任何东西。我想到的一件事是,自动收集统计数据的工作可能会挂在等待下一个跳出的运行日期


还有其他想法吗?

更改系统日期可能不需要重新收集统计信息。表统计信息不包含实际的SYSDATE。即使执行计划对系统日期非常敏感,Oracle似乎也能很好地处理日期更改

然而,如果在某个地方发生了与更改日期有关的奇怪错误,我也不会感到太惊讶。但是您应该向DBA询问具体的细节,包括Oracle支持错误号

下面是优化器完美处理操作系统日期更改的示例

1:删除所有当前缓存的SQL,以防万一

alter system flush shared_pool; 
2:创建一个带有倾斜列的表。今天有很多价值,但明天只有少数价值

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;
/
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 |
----------------------------------------------------------------------------
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 |
----------------------------------------------------------------------------
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)+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 |
----------------------------------------------------------------------------
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 |
----------------------------------------------------------------------------

“在Oracle中更改系统日期”是什么意思?是否要在操作系统级别修改系统日期?你想向前或向后“移动”时间吗?一些表,如
DBA_对象
DBA_表
包含创建的日期或上次分析的日期,这些可能不应包含任何“未来”时间。顺便说一句:您还可以通过配置侦听器将Oracle DB上的系统时间“调整”为OS系统时间。因此,您可以在操作系统级别上拥有“当前”时间,但在Oracle级别上拥有6个小时。如果你为居住在不同时区的某个国家托管一些应用程序,这会很方便;我们曾经用它来测试内务管理程序。在过去,当你可以想走多远就走多远的时候,它更有用;在11g中,您被限制为24小时。我想这是合理的。是的,我们正在改变系统时间。我们向前跳是为了测试年度流程,比如财政年度结束。我们不会回来,我们只是“加快”时间。这是否意味着统计数据有某种失效日期,因此我们必须在这样的跳转之后收集它们(数据和索引不会改变)?@WojtusJ统计数据依赖于所谓的段空间监控。如果超过10%的表段被修改,则该表将被标记为过时,并将在下次统计期间进行分析。收集工作。另一方面,Oracle对
UNDO
表空间的闪回查询有~internal limition~。如果删除的数据超过5天前,Oracle将不允许您查看该数据。个人只需关闭数据库,更改系统(OS) 然后再次启动数据库。