user_tab_modifications 记录着 从上次 收集统计信息后,该表变动的量(如插入有多少行,更新,删除有多少行)
点击(此处)折叠或打开
-
scott@ORCL>desc user_tab_modifications
-
Name Null? Type
-
----------------------------------------- -------- ----------------------------
-
TABLE_NAME VARCHAR2(30)
-
PARTITION_NAME VARCHAR2(30)
-
SUBPARTITION_NAME VARCHAR2(30)
-
INSERTS NUMBER
-
UPDATES NUMBER
-
DELETES NUMBER
-
TIMESTAMP DATE
-
TRUNCATED VARCHAR2(3)
- DROP_SEGMENTS NUMBER
user_tab_statistics 是记录表的统计信息(其实很多统计信息 在user_tables 里也有。这里有一列STALE_STATS表示统计信息是否陈旧。这根据变动记录数量在整体记录数量的比重来决定的。超过三分之一比例的记录变动,会被认为是统计信息陈旧。
点击(此处)折叠或打开
-
scott@ORCL>desc user_tab_statistics
-
Name Null? Type
-
----------------------------------------- -------- ----------------------------
-
TABLE_NAME VARCHAR2(30)
-
PARTITION_NAME VARCHAR2(30)
-
PARTITION_POSITION NUMBER
-
SUBPARTITION_NAME VARCHAR2(30)
-
SUBPARTITION_POSITION NUMBER
-
OBJECT_TYPE VARCHAR2(12)
-
NUM_ROWS NUMBER
-
BLOCKS NUMBER
-
EMPTY_BLOCKS NUMBER
-
AVG_SPACE NUMBER
-
CHAIN_CNT NUMBER
-
AVG_ROW_LEN NUMBER
-
AVG_SPACE_FREELIST_BLOCKS NUMBER
-
NUM_FREELIST_BLOCKS NUMBER
-
AVG_CACHED_BLOCKS NUMBER
-
AVG_CACHE_HIT_RATIO NUMBER
-
SAMPLE_SIZE NUMBER
-
LAST_ANALYZED DATE
-
GLOBAL_STATS VARCHAR2(3)
-
USER_STATS VARCHAR2(3)
-
STATTYPE_LOCKED VARCHAR2(5)
- STALE_STATS VARCHAR2(3)
点击(此处)折叠或打开
-
scott@ORCL>create table tab_test as select * from dba_objects;
-
-
Table created.
-
scott@ORCL>analyze table tab_test compute statistics;
-
-
Table analyzed.
-
-
scott@ORCL>select table_name, num_rows, blocks, stale_stats from user_tab_statistics
-
2 where table_name = \'TAB_TEST\';
-
-
TABLE_NAME NUM_ROWS BLOCKS STA
-
--------- --------- ------ --- -- 刚收集 统计不陈旧 stale_stats 为 NO
- TAB_TEST 76511 1116 NO
插入3万行数据。数据变动过了30%。
点击(此处)折叠或打开
-
scott@ORCL>insert into tab_test select * from tab_test where rownum <= 30000;
-
-
30000 rows created.
-
-
scott@ORCL>commit;
-
- Commit complete.
点击(此处)折叠或打开
-
scott@ORCL>select table_name, inserts, deletes, updates, to_date(timestamp, \'yyyy-mm-dd hh24:mi:ss\') time, truncated
-
2 from user_tab_modifications
-
3 where table_name = \'TAB_TEST\';
-
-
no rows selected
-
-
scott@ORCL>select table_name, num_rows, blocks, stale_stats from user_tab_statistics
-
2 where table_name = \'TAB_TEST\';
-
-
TABLE_NAME NUM_ROWS BLOCKS STA
-
------------------------------ ---------- ---------- ---
- TAB_TEST 76511 1116 NO
点击(此处)折叠或打开
-
scott@ORCL>exec dbms_stats.flush_database_monitoring_info;
-
BEGIN dbms_stats.flush_database_monitoring_info; END;
-
-
*
-
ERROR at line 1:
-
ORA-20000: Insufficient privileges
-
ORA-06512: at \"SYS.DBMS_STATS\", line 4535
-
ORA-06512: at \"SYS.DBMS_STATS\", line 25376
- ORA-06512: at line 1
手动刷新,出错了。需要用sys用户授权
点击(此处)折叠或打开
-
scott@ORCL>conn /as sysdba
-
Connected.
-
sys@ORCL>grant ANALYZE any to scott;
-
-
Grant succeeded.
-
sys@ORCL>conn scott/tiger
-
Connected.
-
scott@ORCL>exec dbms_stats.flush_database_monitoring_info;
-
- PL/SQL procedure successfully completed.
点击(此处)折叠或打开
-
scott@ORCL>select table_name, inserts, deletes, updates, to_date(timestamp, \'yyyy-mm-dd hh24:mi:ss\'), truncated
-
2 from user_tab_modifications
-
3 where table_name = \'TAB_TEST\';
-
-
TABLE_NAME INSERTS DELETES UPDATES TO_DATE(T TRU
-
------------------------------ ---------- ---------- ---------- --------- ---
-
TAB_TEST 30000 0 0 14-JUN-05 NO -- 从上一次收集统计后,插入了30000行 被记录下来了
-
-
scott@ORCL>select table_name, num_rows, blocks, stale_stats from user_tab_statistics
-
2 where table_name = \'TAB_TEST\';
-
-
TABLE_NAME NUM_ROWS BLOCKS STA
-
------------------------------ ---------- ---------- ---
- TAB_TEST 76511 1116 YES -- stale_stats 列显示 YES, 统计信息被判定为陈旧
说明完,统计信息陈旧问题。回到SQL Tuning Advisor 对 统计信息陈旧的问题的改动建议。
注意:这里STA会自己比较当前统计信息和之前的统计信息,自行判定统计是否陈旧,不需要理会user_tab_statistics的stale_stats列。
再插入106511行
点击(此处)折叠或打开
-
scott@ORCL>insert into tab_test select * from tab_test;
-
-
106511 rows created.
-
- scott@ORCL>commit;
待优化的sql。执行时,统计信息已经陈旧。
点击(此处)折叠或打开
- scott@ORCL>select /* stat_stale */ count(*) from tab_test;
先获取相应的sqlid
点击(此处)折叠或打开
-
sys@ORCL>var task_name varchar2(50)
-
sys@ORCL> begin
-
2 select sql_id INTO :sql_id from v$sql where sql_text like \'select /* stat_stale */ count(*)%\' and rownum = 1;
-
3 end;
-
4 /
-
-
PL/SQL procedure successfully completed.
-
-
sys@ORCL>print :sql_id;
-
-
SQL_ID
-
--------------------------------------------------------------------------------------------------------------------------------
-
gaqzn7k394m52
-
-
sys@ORCL>select sql_text from v$sql where sql_id = \'gaqzn7k394m52\';
-
-
SQL_TEXT
-
----------------------------------------------------------------------------------------------------------------------------------------------------------------
- select /* stat_stale */ count(*) from tab_test
创建STA任务,并且执行
点击(此处)折叠或打开
-
var task_name varchar2(50)
-
-
sys@ORCL>begin
-
2 :task_name := dbms_sqltune.create_tuning_task(sql_id => :sql_id); -- 创建优化任务
-
3 dbms_sqltune.execute_tuning_task(:task_name); -- 执行优化任务
-
4 end;
-
5 /
-
- PL/SQL procedure successfully completed.
点击(此处)折叠或打开
-
sys@ORCL>select dbms_sqltune.report_tuning_task(:task_name) from dual;
-
-
DBMS_SQLTUNE.REPORT_TUNING_TASK(:TASK_NAME)
-
--------------------------------------------------------------------------------
-
GENERAL INFORMATION SECTION
-
-------------------------------------------------------------------------------
-
Tuning Task Name : TASK_620
-
Tuning Task Owner : SYS
-
Workload Type : Single SQL Statement
-
Scope : COMPREHENSIVE
-
Time Limit(seconds): 1800
-
Completion Status : COMPLETED
-
Started at : 06/05/2014 23:22:22
-
Completed at : 06/05/2014 23:22:23
-
-
-------------------------------------------------------------------------------
-
Schema Name: SCOTT
-
SQL ID : gaqzn7k394m52
-
SQL Text : select /* stat_stale */ count(*) from tab_test
-
-
-------------------------------------------------------------------------------
-
FINDINGS SECTION (1 finding)
-
-------------------------------------------------------------------------------
-
-
1- Statistics Finding
-
---------------------
-
Optimizer statistics for table \"SCOTT\".\"TAB_TEST\" and its indices are stale. -- 这里指出统计信息陈旧
-
-
Recommendation
-
--------------
-
- Consider collecting optimizer statistics for this table.
-
execute dbms_stats.gather_table_stats(ownname => \'SCOTT\', tabname => -- STA提供了重新收集的统计信息的语句
-
\'TAB_TEST\', estimate_percent => DBMS_STATS.AUTO_SAMPLE_SIZE,
-
method_opt => \'FOR ALL COLUMNS SIZE AUTO\');
-
-
Rationale
-
---------
-
The optimizer requires up-to-date statistics for the table in order to
-
select a good execution plan.
-
-
-------------------------------------------------------------------------------
-
EXPLAIN PLANS SECTION
-
-------------------------------------------------------------------------------
-
-
1- Original
-
-----------
-
Plan hash value: 2448592499
-
-
-----------------------------------------------------------------------
-
| Id | Operation | Name | Rows | Cost (%CPU)| Time |
-
-----------------------------------------------------------------------
-
| 0 | SELECT STATEMENT | | 1 | 305 (1)| 00:00:04 |
-
| 1 | SORT AGGREGATE | | 1 | | |
-
| 2 | TABLE ACCESS FULL| TAB_TEST | 76511 | 305 (1)| 00:00:04 |
-
-----------------------------------------------------------------------
-
按照STA给语句,执行一下收集统计的语句
点击(此处)折叠或打开
-
scott@ORCL>begin
-
dbms_stats.gather_table_stats(ownname => \'SCOTT\', tabname =>
-
\'TAB_TEST\', estimate_percent => DBMS_STATS.AUTO_SAMPLE_SIZE,
-
method_opt => \'FOR ALL COLUMNS SIZE AUTO\');
-
end;
-
/
-
- PL/SQL procedure successfully completed.