select count(a.id) from LARGE_PARTITIONED_TABLE a join SMALL_NONPARTITIONED_TABLE b on a.key1 = b.key1 and a.key2 = b.key2 where b.id = 1000
表LARGE_PARTITIONED_TABLE(a)有大约500万行,并由查询中不存在的列分区.表SMALL_NONPARTITIONED_TABLE(b)未分区,并保存大约10000行.
统计数据是最新的,并且表a的列key1和key2中有高度平衡的直方图.
表a具有主键和列key1,key2,key3,key4和key5上的全局非分区唯一索引.
查询解释计划显示以下结果:
--------------------------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | --------------------------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | 31 | 4 (0)| 00:00:01 | | 1 | SORT AGGREGATE | | 1 | 31 | | | | 2 | NESTED LOOPS | | 406 | 12586 | 4 (0)| 00:00:01 | |* 3 | INDEX RANGE SCAN| INDEX_ON_TABLE_B | 1 | 19 | 2 (0)| 00:00:01 | |* 4 | INDEX RANGE SCAN| PRIMARY_KEY_INDEX_OF_TABLE_A | 406 | 4872 | 2 (0)| 00:00:01 | --------------------------------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 3 - access("b"."id"=1000) 4 - access("a"."key1"="b"."key1" and "a"."key2"="b"."key2")
因此,针对步骤4估计的行(基数)是406.
现在,tkprof跟踪显示以下内容:
Rows Row Source Operation ------- --------------------------------------------------- 1 SORT AGGREGATE (cr=51 pr=9 pw=0 time=74674 us) 7366 NESTED LOOPS (cr=51 pr=9 pw=0 time=824941 us) 1 INDEX RANGE SCAN INDEX_ON_TABLE_B (cr=2 pr=0 pw=0 time=36 us)(object id 111111) 7366 INDEX RANGE SCAN PRIMARY_KEY_INDEX_OF_TABLE_A (cr=49 pr=9 pw=0 time=810173 us)(object id 222222)
所以现实中的基数是7366,而不是406!
我的问题是:在这种情况下,Oracle从哪里获得406的估计基数,以及如何提高其准确性,以便估计更符合查询执行期间的实际情况?
更新:这是我在查询上运行的10053跟踪的片段.
NL Join Outer table: Card: 1.00 Cost: 2.00 Resp: 2.00 Degree: 1 Bytes: 19 Inner table: LARGE_PARTITIONED_TABLE Alias: a ... Access Path: index (IndexOnly) Index: PRIMARY_KEY_INDEX_OF_TABLE_A resc_io: 2.00 resc_cpu: 27093 ix_sel: 1.3263e-005 ix_sel_with_filters: 1.3263e-005 NL Join (ordered): Cost: 4.00 Resp: 4.00 Degree: 1 Cost_io: 4.00 Cost_cpu: 41536 Resp_io: 4.00 Resp_cpu: 41536 ****** trying bitmap/domain indexes ****** Best NL cost: 4.00 resc: 4.00 resc_io: 4.00 resc_cpu: 41536 resp: 4.00 resp_io: 4.00 resp_cpu: 41536 Using concatenated index cardinality for table SMALL_NONPARTITIONED_TABLE Revised join sel: 8.2891-e005 = 8.4475e-005 * (1/12064.00) * (1/8.4475e-005) Join Card: 405.95 = outer (1.00) * inner (4897354.00) * sel (8.2891-e005) Join Card - Rounded: 406 Computed: 405.95
这就是价值406的来源.像Adam回答的那样,加入基数是加入选择性*过滤基数(a)*过滤基数(b),可以在上面跟踪引用的倒数第二行看到.
我不明白的是Revised join sel line. 1/12064是用于从表b中查找行的索引的选择性(表上的12064行,并且基于唯一ID进行选择).但那又怎么样?
>基数似乎是通过计算得出的
乘以滤波器基数
表b(4897354)与
表a的选择性(1/12064).
为什么?什么
做选择性
表a与多少有关
预计将从中找到行
表b,当a – > b加入不是基于
援助?
>数字在哪里
8.4475e-005来自(它不会出现在整个其他地方
跟踪)?不是它影响了
输出,但我还是想知道.
我知道优化器可能在这里选择了正确的路径.但是基数仍然被误算 – 并且这可能对从该点开始选择的执行路径产生重大影响(就像我有IRL的情况一样 – 这个例子是对它的简化).
从那项工作:
Join Selectivity = ((num_rows(t1) - num_nulls(t1.c1)) / num_rows(t1)) * ((num_rows(t2) - num_nulls(t2.c2)) / num_rows(t2)) / greater (num_distinct(t1.c1),num_distinct(t2.c2)) Join Cardinality = Join Selectivity * filtered_cardinality (t1) * filtered_cardinality (t2)
但是,因为我们有一个多列连接,所以Join Selectivity不在表级别,它是每列上连接选择性的乘积(交集).假设游戏中没有空值:
Join Selectivity = Join Selectivity (key1) * Join Selectivity (key2) Join Selectivity (key1) = ((5,000,000 - 0) / 5,000) * ((10,000 - 0)) / 10,000) / max (116,?) -- distinct key1 values in B = 1 / max(116,distinct_key1_values_in_B) Join Selectivity (key2) = ((5,000) / max (650,?) -- distinct key2 values in B = 1 / max(650,distinct_key2_values in B) Join Cardinality = JS(key1) * JS(key2) * Filter_cardinality(a) * Filter_cardinality(b)
我们知道A上没有过滤器,因此表格过滤器基数是行数.我们从B中选择键值,因此表的过滤基数为1.
因此,估计估计加入基数的最佳情况是现在
Join Cardinality = 1/116 * 1/650 * 5,000 * 1 =~ 67
向后工作可能更容易.根据我们所知,您的估计基数为406,导致加入选择性为406 / 5,即大约1/12315.这恰好是非常接近1 /(116 ^ 2),这是优化器中的一个健全性检查,以防止它在多列连接上找到过于激进的基数.
对于TL; DR人群:
>获取Jonathan Lewis的基于成本的Oracle基础知识.>获取10053跟踪您的行为无法理解的查询.
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。