【问题标题】:Oracle - Column Histograms Showing NONE even after GATHER_TABLE_STATSOracle - 即使在 GATHER_TABLE_STATS 之后也显示 NONE 的列直方图
【发布时间】:2019-08-21 21:52:10
【问题描述】:

我正在尝试对使用窗口分区的 Oracle 12c 中的 SQL 查询进行性能调整。在 PIT 表的 HUB_POL_KEY、PIT_EFF_START_DT 上创建了一个索引。在使用 /*+gather_plan_statistics */ 提示运行解释计划时,我观察到解释计划中有一个窗口排序步骤,其估计行数为 5000K,实际行数为 1100。我在表上执行了 DBMS_STATS.GATHER_TABLE_STATS .当我检查 USER_TAB_COLUMNS 表时,我看到没有为 HUB_POL_KEY PIT_EFF_START_DT 生成直方图。但是,所有其他列都存在直方图。

SQL 查询

SELECT 
PIT.HUB_POL_KEY,
NVL(LEAD(PIT.PIT_EFF_START_DT) OVER (PARTITION BY PIT.HUB_POL_KEY ORDER BY PIT.PIT_EFF_START_DT) ,TO_DATE('31.12.9999', 'DD.MM.YYYY')) EFF_END_DT
FROM PIT

第一次尝试:

EXEC DBMS_STATS.GATHER_TABLE_STATS('stg','PIT');

第二次尝试:

EXEC DBMS_STATS.GATHER_TABLE_STATS('stg','PIT', method_opt=>('FOR COLUMNS SIZE 254 (HUB_POL_KEY,PIT_EFF_START_DT)'));

检查直方图:

SELECT HISTOGRAM FROM USER_TAB_COLUMNS
WHERE TABLE_NAME = 'PIT'
AND COLUMN_NAME IN ('HUB_POL_KEY','PIT_EFF_START_DT') --NONE

表格统计:

SELECT COUNT(*) FROM PIT --5570253

SELECT COLUMN_NAME,NUM_DISTINCT,NUM_BUCKETS,HISTOGRAM FROM USER_TAB_COL_STATISTICS
WHERE TABLE_NAME = 'PIT'
AND COLUMN_NAME IN ('HUB_POL_KEY','PIT_EFF_START_DT')
+------------------+--------------+-------------+-----------+
|   COLUMN_NAME    | NUM_DISTINCT | NUM_BUCKETS | HISTOGRAM |
+------------------+--------------+-------------+-----------+
| HUB_POL_KEY      |      4703744 |           1 | NONE      |
| PIT_EFF_START_DT |       154416 |           1 | NONE      |
+------------------+--------------+-------------+-----------+

我在这里缺少什么?为什么即使我在 method_opt 指定大小的情况下运行gather_table_stat 过程,存储桶大小仍为 1?

【问题讨论】:

    标签: oracle performance oracle12c table-statistics


    【解决方案1】:

    按照Oracle documentation 的正确语法应该是method_opt=>('FOR COLUMNS (HUB_POL_KEY,PIT_EFF_START_DT) SIZE 254')。尝试它并没有像预期的那样创建直方图统计信息(可能是一个错误¯_(ツ)_/¯)。

    另一方面,使用method_opt=>('FOR ALL COLUMNS SIZE 254')method_opt=>('FOR COLUMNS <column_name> SIZE 254') 工作正常。

    可能的解决方法是分别收集列的统计信息:

    EXEC DBMS_STATS.GATHER_TABLE_STATS('stg','PIT', method_opt=>('FOR COLUMNS HUB_POL_KEY SIZE 254'));
    EXEC DBMS_STATS.GATHER_TABLE_STATS('stg','PIT', method_opt=>('FOR COLUMNS PIT_EFF_START_DT SIZE 254'));
    

    【讨论】:

    • 在不同的列上分别执行 GATHER_TABLE_STATS 解决了这个问题。非常感谢:)
    猜你喜欢
    • 2020-10-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-19
    • 2020-02-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多