我有两个返回相同结果集的查询,但是在查看执行计划时,它们具有不同的基数值。
查询是:
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%';
Run Code Online (Sandbox Code Playgroud)
和
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;
Run Code Online (Sandbox Code Playgroud)
第一个查询具有以下说明计划:
--------------------------------------------------------------------------------
| 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%')
Run Code Online (Sandbox Code Playgroud)
第二个查询的解释计划是:
--------------------------------------------------------------------------------
| 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 )
Run Code Online (Sandbox Code Playgroud)
我的问题是为什么两个执行计划之间的基数不同?对于第一个计划,基数(行)为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还支持扩展的统计信息,您可以在其中计算特定表达式或相关列的统计信息和直方图。
| 归档时间: |
|
| 查看次数: |
445 次 |
| 最近记录: |