Oracle - 即使在 GATHER_TABLE_STATS 之后,列直方图仍显示 NONE
Oracle - Column Histograms Showing NONE even after GATHER_TABLE_STATS
我正在尝试对使用 window 分区的 Oracle 12c 中的 SQL 查询进行性能调整。在 HUB_POL_KEY、PIT_EFF_START_DT 和 table PIT 上创建了一个索引。虽然 运行 带有 /*+ gather_plan_statistics */ 提示的解释计划,但我观察到解释计划中有一个 Window 排序步骤,估计行数为 5000K,实际行数为计数 1100。我在 table 上执行了 DBMS_STATS.GATHER_TABLE_STATS。当我签入 USER_TAB_COLUMNS table 时,我发现没有为 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
Table 统计:
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 |
+------------------+--------------+-------------+-----------+
我在这里错过了什么?为什么即使我 运行 gather_table_stat 程序 method_opt 指定大小,桶大小也是 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'));
我正在尝试对使用 window 分区的 Oracle 12c 中的 SQL 查询进行性能调整。在 HUB_POL_KEY、PIT_EFF_START_DT 和 table PIT 上创建了一个索引。虽然 运行 带有 /*+ gather_plan_statistics */ 提示的解释计划,但我观察到解释计划中有一个 Window 排序步骤,估计行数为 5000K,实际行数为计数 1100。我在 table 上执行了 DBMS_STATS.GATHER_TABLE_STATS。当我签入 USER_TAB_COLUMNS table 时,我发现没有为 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
Table 统计:
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 |
+------------------+--------------+-------------+-----------+
我在这里错过了什么?为什么即使我 运行 gather_table_stat 程序 method_opt 指定大小,桶大小也是 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'));