我有两个查询返回相同的结果集,但在检查执行计划时它们具有不同的基数值。
查询是:
select acq_cod
, prp
, df_val
, descr
from acqdefprp
where (prp like '%pswd%' or prp like '%Pswd%')
and prp not like '%kno%'
and prp not like '%encr%';
和
select acq_cod
, prp
, df_val
, descr
from acqdefprp
where regexp_instr(prp, 'pswd', 1,1,0,'i' ) > 0
and regexp_instr(prp, '(encr)|(kno)', 1,1,0,'i' ) = 0;
第一个查询具有以下解释计划:
--------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 65 | 4485 | 6 (0)| 00:00:01 |
|* 1 | TABLE ACCESS FULL| acqdefprp | 65 | 4485 | 6 (0)| 00:00:01 |
--------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter(("PRP" LIKE '%pswd%' OR "PRP" LIKE '%Pswd%')
AND "PRP" NOT LIKE '%kno%'
AND "PRP" NOT LIKE '%encr%')
第二个查询的解释计划是:
--------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 69 | 6 (0)| 00:00:01 |
|* 1 | TABLE ACCESS FULL| acqdefprp | 1 | 69 | 6 (0)| 00:00:01 |
--------------------------------------------------------------------------------
1 - filter(REGEXP_INSTR ("PRP",'(encr)|(kno)',1,1,0,'i') = 0
AND REGEXP_INSTR ("PRP",'pswd',1,1,0,'i') > 0 )
我的问题是为什么两个执行计划之间的基数不同?对于第一个计划,基数(行)是 65,第二个计划是 1?
我的假设是,如果单独评估每个条件,则此基数是每个条件将返回的最大行数,并且所有这些都基于表统计信息。这就是为什么我的第一个查询假定最大值为 65,因为 WHERE
条件稍微宽松一些。
这也是为什么第二个查询的基数为 1,因为 regexp_instr
的限制性更强。
如果我的假设不正确,我真的很想知道是什么决定了这个基数。
预先感谢您的帮助
最佳答案
在您的情况下,表达式太复杂,优化器无法使用基本统计数据来估计基数。在这些情况下(您似乎没有使用可能影响 LIKE
谓词的直方图),使用固定选择性:
等号运算符:1% 不等式运算符:5%
所以你的
LIKE
示例大约占表格总行数的 (5 % + 5 % - (5 % * 5 %)) * 95 % * 95 % => 8.8 %
。 - (5 % * 5 %)
是由于 OR
运算符而产生的交集。
REGEX
示例是表总行数的 1 % * 5 % => 0.05 %
。
Oracle 还支持扩展统计信息,您可以在其中计算特定表达式或相关列的统计信息和直方图。
关于oracle - 查询中的基数是如何确定的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33611207/