我将此子查询作为更大查询的一部分:
SELECT *
from totals a
where A.COMPANY ='TTT'
AND A.LOGISTIC_COMP = '111'.
此表有~32M行,以及此查询中的行数,这些参数返回~9M行。
我看到不同的参数(公司,logistic_company),我有不同的表现。
我查了一下,发现这个栏目有很大的分布, 它会导致优化器估计基数错误。
所以我使用这个语句在那些列上创建直方图:
EXEC DBMS_STATS.GATHER_TABLE_STATS ('MY_SCHEMA', 'TOTALS',METHOD_OPT => 'FOR ALL COLUMNS SIZE 1 FOR COLUMNS company size 254, logistic_comp size 254');
但即使在那之后 - 基数仍然存在错误!
优化器认为有~2.5M行而不是〜9M。
计划使用的索引(具有此基数)是最新的..
是有意义的吗?
答案 0 :(得分:4)
很可能您的列是相关的。 Oracle无法计算两列的统计信息。您可以为列对创建统计信息。它被称为扩展统计
如本link.所述。在后台,Oracle将创建不可见的虚拟列,它表示COMPANY和LOGISTIC_COMP的连接。
您还应该使用提示GATHER_PLAN_STATISTICS.
检查实际的基数创建扩展统计信息
SELECT DBMS_STATS.CREATE_EXTENDED_STATS(null, 'TOTALS', '(COMPANY,LOGISTIC_COMP)')
FROM DUAL;
使用GATHER_PLAN_STATISTICS提示执行查询
SELECT /*+ gather_plan_statistics */ *
from totals a
where A.COMPANY = 'TTT'
AND A.LOGISTIC_COMP = '111';
检查A-ctual与E-stimated基数
SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY_CURSOR(NULL, NULL, 'ALLSTATS LAST'));
PS:从版本12c开始,Oracle会在列集上创建这些扩展统计信息。