database - SYSDATE 更改会影响 Oracle 中的表统计信息吗?

标签 database oracle oracle11g database-administration

我们的一位数据库管理员说,在更改 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/

相关文章:

mysql - 如何通过shell命令删除mysql数据库

Oracle Forms 设置项无效

oracle11g - Oracle express 11g 如何使用 "create database"语句?

sql - 断开 RDS Oracle 数据库上的所有用户连接

php - [PHP + MySQL]数据库SELECT查询未返回结果

sql - 如何在 PostgreSQL 中仅列出表的属性名称

mysql - RDS 实例 CPU 利用率

java - 使用 JDBC 读取 Oracle DB 中的 XMLType 列

oracle - Oracle PL/SQL 数组的索引是从 0 还是从 1?

java - 尝试使用 Oracle + Spring Data Jpa 查询存储过程(存储函数)时出现错误