SQL调优指南笔记16:Managing Historical Optimizer Statistics

Posted dingdingfish

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SQL调优指南笔记16:Managing Historical Optimizer Statistics相关的知识,希望对你有一定的参考价值。

本文为SQL Tuning Guide第16章“Managing Historical Optimizer Statistics”的笔记。

本章讲述如何保留、报告和恢复非当前统计信息。

16.1 Restoring Optimizer Statistics

您可以使用 DBMS_STATS 恢复存储在数据字典中的旧版本的统计信息。

16.1.1 About Restore Operations for Optimizer Statistics

每当修改数据字典中的统计信息时,数据库会自动保存旧版本的统计信息。 如果新收集的统计信息导致执行计划不理想,那么您可能希望恢复到以前的统计信息。

恢复优化器统计信息有助于解决次优计划。 下图说明了恢复统计数据的时间线。 在图中,统计信息收集发生在 8 月 10 日和 8 月 20 日。8 月 24 日,DBA 确定当前统计信息可能导致优化器生成次优计划。 8 月 25 日,管理员恢复了 8 月 10 日收集的统计信息。

16.1.2 Guidelines for Restoring Optimizer Statistics

恢复统计数据类似于导入和导出统计数据。

通常,在以下情况下,还原统计信息而不是导出统计信息:

  • 您想要恢复旧版本的统计信息。 例如,您希望将优化器行为恢复到更早的日期。
  • 您希望数据库管理统计历史记录的保留和清除。

在以下情况下导出统计信息而不是恢复它们:

  • 您想试验多组统计数据并来回更改值。
  • 您希望将统计信息从一个数据库移动到另一个数据库。 例如,将统计数据从生产系统转移到测试系统。
  • 您希望将一组已知的统计数据保留比恢复统计数据所需的保留日期更长的时间。

16.1.3 Restrictions for Restoring Optimizer Statistics

恢复以前版本的统计信息时,存在各种限制。

限制包括以下内容:

  • DBMS_STATS.RESTORE_*_STATS 过程无法恢复用户定义的统计信息。
  • 当使用 ANALYZE 命令收集统计信息时,不存储旧版本的统计信息。
  • 删除表会删除自动直方图功能使用的工作负载数据和 DBMS_STATS.RESTORE_*_STATS 使用的统计历史记录。 如果没有这些数据,这些功能将无法正常工作。 因此,要从表中删除所有行并重新填充它,Oracle 建议使用 TRUNCATE 而不是DROP并重新创建表。

注意:如果表驻留在回收站中,则闪回该表也会检索统计信息。

16.1.4 Restoring Optimizer Statistics Using DBMS_STATS

您可以使用 DBMS_STATS.RESTORE_*_STATS 过程恢复统计信息。

下表中列出的过程接受时间戳作为参数并恢复指定时间 (as_of_timestamp) 的统计信息。

表 16-1 DBMS_STATS 恢复过程

过程描述
RESTORE_DICTIONARY_STATS恢复指定时间戳的所有字典表(SYS、SYSTEM 和 RDBMS 组件模式的表)的统计信息。
RESTORE_FIXED_OBJECTS_STATS恢复指定时间戳的所有固定表的统计信息。
RESTORE_SCHEMA_STATS从指定的时间戳恢复模式的所有表的统计信息。
RESTORE_SYSTEM_STATS恢复指定时间戳的系统统计信息。
RESTORE_TABLE_STATS从指定的时间戳恢复表的统计信息。 该过程还恢复关联索引和列的统计信息。 如果表统计信息在指定的时间戳被锁定,则该过程将锁定统计信息。

字典视图显示统计修改的时间。 您可以使用以下视图来确定要用于还原操作的时间戳:

  • DBA_OPTSTAT_OPERATIONS 视图包含使用 DBMS_STATS 在模式和数据库级别执行的统计操作的历史记录。
  • DBA_TAB_STATS_HISTORY 视图包含表统计信息修改的历史记录。

本教程假定以下内容:

  • 在 oe.orders 表的最新统计信息收集之后,优化器开始为该表的查询选择次优计划。
  • 您希望从最近的统计信息收集之前恢复统计信息,以查看计划是否有所改进。
-- 查询 oe.orders 的统计历史。
COL TABLE_NAME FORMAT a10
SELECT TABLE_NAME,
       TO_CHAR(STATS_UPDATE_TIME,'YYYY-MM-DD:HH24:MI:SS') AS STATS_MOD_TIME
FROM   DBA_TAB_STATS_HISTORY 
WHERE  TABLE_NAME='ORDERS'
AND    OWNER='OE'
ORDER BY STATS_UPDATE_TIME DESC;

TABLE_NAME STATS_MOD_TIME     
---------- -------------------
ORDERS     2022-06-07:08:21:15
ORDERS     2022-06-05:21:54:05
ORDERS     2022-06-05:21:51:48
ORDERS     2022-06-05:21:51:31
ORDERS     2022-06-04:06:46:49

-- 将优化器统计信息恢复到之前的修改时间。
BEGIN
  DBMS_STATS.RESTORE_TABLE_STATS( 'OE','ORDERS', 
               TO_TIMESTAMP('2022-06-04:06:46:49','YYYY-MM-DD:HH24:MI:SS') );
END;
/

16.2 Managing Optimizer Statistics Retention

默认情况下,数据库将优化器统计信息保留 31 天,之后计划清除统计信息。

您可以使用 DBMS_STATS 包来确定保留期限、更改期限以及手动清除旧的统计信息。

16.2.1 Obtaining Optimizer Statistics History

您可以使用 DBMS_STATS 过程来获取优化器统计信息的历史信息。

当您想要确定数据库保留优化器统计信息的时间以及这些统计信息可以恢复多长时间时,历史信息很有用。 您可以使用以下过程来获取有关优化器统计历史记录的信息:

  • GET_STATS_HISTORY_RETENTION
    该函数可以检索当前的统计历史保留值。
  • GET_STATS_HISTORY_AVAILABILITY
    当统计历史可用时,此函数检索最旧的时间戳。 用户无法将统计信息恢复到比最旧时间戳更早的时间戳。
SET SERVEROUTPUT ON

DECLARE
  v_stats_retn  NUMBER;
  v_stats_date  DATE;
BEGIN
  v_stats_retn := DBMS_STATS.GET_STATS_HISTORY_RETENTION;
  DBMS_OUTPUT.PUT_LINE('The retention setting is ' || 
    v_stats_retn || '.');
  v_stats_date := DBMS_STATS.GET_STATS_HISTORY_AVAILABILITY;
  DBMS_OUTPUT.PUT_LINE('Earliest restore date is ' ||
    v_stats_date || '.');
END;
/

The retention setting is 31.
Earliest restore date is 07-MAY-22.

16.2.2 Changing the Optimizer Statistics Retention Period

您可以使用 DBMS_STATS.ALTER_STATS_HISTORY_RETENTION 过程配置保留期。 默认值为 31 天。

要运行此过程,您必须具有 SYSDBA 特权,或同时具有 ANALYZE ANY DICTIONARY 和 ANALYZE ANY 系统特权。

本教程假定以下内容:

  • 优化器统计信息的当前保留期为 31 天。
  • 作为年度报告的一部分,您每年都会运行查询。 要将统计历史记录保留 365 天以上,以便您可以访问去年的计划(以防现在出现次优计划),请将保留期设置为 366 天。
  • 您想要创建一个 PL/SQL 过程 set_opt_stats_retention,您可以使用它来更改优化器统计信息的保留期。

要更改优化器统计信息保留期:

-- 创建一个更改保留期的过程。
CREATE OR REPLACE PROCEDURE set_opt_stats_retention
  ( p_stats_retn   IN NUMBER )
IS
  v_stats_retn NUMBER;
BEGIN
  v_stats_retn := DBMS_STATS.GET_STATS_HISTORY_RETENTION;
  DBMS_OUTPUT.PUT_LINE('Old retention setting is ' ||
    v_stats_retn || '.');
  DBMS_STATS.ALTER_STATS_HISTORY_RETENTION(p_stats_retn);
  v_stats_retn := DBMS_STATS.GET_STATS_HISTORY_RETENTION;
  DBMS_OUTPUT.PUT_LINE('New retention setting is ' ||
    v_stats_retn || '.');
END;
/

EXECUTE set_opt_stats_retention(366)

The old retention setting is 31.
The new retention setting is 366.

DROP PROCEDURE set_opt_stats_retention;

16.2.3 Purging Optimizer Statistics

当 STATISTICS_LEVEL 初始化参数设置为 TYPICAL 或 ALL 时,将启用自动清除。

数据库清除所有早于以下两个时间中较早的一个的历史:

  • (当前时间 - ALTER_STATS_HISTORY_RETENTION 设置)
  • (最近的统计信息收集时间 - 1)。

您可以使用 PURGE_STATS 过程手动清除旧的统计信息。 如果不指定参数,则此过程使用自动清除策略。 如果您指定 before_timestamp 参数,那么数据库会清除在指定时间戳之前保存的统计信息。

要运行此过程,您必须具有 SYSDBA 特权,或同时具有 ANALYZE ANY DICTIONARY 和 ANALYZE ANY 系统特权。

本教程假设您要清除超过一周的统计信息。

EXEC DBMS_STATS.PURGE_STATS( SYSDATE-7 );

16.3 Reporting on Past Statistics Gathering Operations

您可以使用 DBMS_STATS 函数来报告特定的统计信息收集操作或在指定时间内发生的操作。

来自不同 PDB 的不同操作可能具有相同的操作 ID。 如果未提供 PDB ID,则报告可能包含多个操作。

表 16-2 DBMS_STATS 报告函数

函数描述
REPORT_STATS_OPERATIONS生成在两个时间点之间发生的所有统计操作的报告。 您可以缩小报告范围以仅包括自动统计收集运行。 您还可以使用 container_ids 提供一组容器 ID,以便数据库仅报告来自指定 PDB 的统计操作。
REPORT_SINGLE_STATS_OPERATION生成指定操作的报告。 您可以使用 container_id 来指定特定的 PDB。

本教程假设您要生成以下内容的 html 报告:

  • 最近一天内的所有统计数据收集操作
  • 最近的统计数据收集操作
SET LINES 200 PAGES 0
SET LONG 100000
COLUMN REPORT FORMAT A200

VARIABLE my_report CLOB;
BEGIN
  :my_report := DBMS_STATS.REPORT_STATS_OPERATIONS (
     since        => SYSDATE-1
,    until        => SYSDATE 
,    detail_level => 'TYPICAL' 
,    format       => 'HTML'      
);
END;
/

print my_report;

输出报告如下:

查看单个操作:

VARIABLE my_report CLOB;

BEGIN
  :my_report :=DBMS_STATS.REPORT_SINGLE_STATS_OPERATION (
     OPID    => 731
,    FORMAT  => 'HTML'
);
END;
/

print my_report;

输出如下:

以上是关于SQL调优指南笔记16:Managing Historical Optimizer Statistics的主要内容,如果未能解决你的问题,请参考以下文章

SQL调优指南笔记14:Managing Extended Statistics

SQL调优指南笔记14:Managing Extended Statistics

SQL调优指南笔记9:Joins

SQL调优指南笔记9:Joins

SQL调优指南笔记1:Introduction to SQL Tuning

SQL调优指南笔记6:Explaining and Displaying Execution Plans