基于成本的oracle的优化法则(一):单表选择率

本文探讨了Oracle优化器如何计算单表选择率,涉及单列谓词和区间谓词的选择率估算,以及绑定变量和联合谓词的影响。通过实例解释了包含in-list查询的特殊行为,并引用概率论基础公式阐述计算原理。优化器的计算可能因数据相关性而产生误差,提醒我们理解其内在机制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

     为了估计一组谓词返回数据的行数,优化器首先计算选择率(返回数据行数的分数),然后将其与输入行数相乘。

     对于单个列上的单个谓词,优化器将利用不同值的数目或者density作为计算谓词选择率的基础。对于单个列上基于区间的谓词,优化器采用对分数range required/total available rang 进行一些端点值调整的方式来计算谓词选择率,比如在统计1200人中有多少人出生在8月以后的(包括8月)即谓词为month >=8,假设按照均匀分部选择率计算如下(要注意开闭区间的情形,闭区间还要再加上1/num_distinct):(12-8)/(12-1)+1/12。

     对于包含绑定变量的区间谓词来说,优化器使用硬编码常量作为选择率-无边界的区间为5%(0.05),有边界的区间为0.25%(0.0025)。

     优化器通过使用类似于计算独立事件的联合概率公式来计算联合谓词的的选择率。如果列中包含的数据集并不是相互独立的话,在选择率的计算方面将会出现误差,从而导致基数出现误差。

     包含in-list的查询显现出一些特殊的行为。在oracle 8i中,in和not in的处理是自相容的(但是错误的)。在oracle9i和10g中,in的处理方式得到了修正,但是针对带有绑定变量的列表或者查询超过了列的期望值时仍将导致错误。

附录1:

概率论方面的基础公式

  • P(A and B) = P(A)*P(B)
  • P(A or B) = P(A)+P(B)-P(A and B)
  • P(not A) = 1-P(A)

附录2(机器不是人):

计算的谓词条件如下: where month > 8 or month <=8

  • 利用简单的选择计算率计算month >8的公式 (12-8)/(12-1) = 4/11 = 0.3636
  • 计算 month <=8 的公式(8-1)/(12-1) = 7/11 = 0.7196
  • 计算or操作的概率为 =(0.3636+0.7196) - 0.3636*0.7196 = 0.8216。因此最后的计算结果为1200*0.8216=986,并不等于1200。机器不是人,它只能按照指定的算法执行。

 

 

目 录 第1章 成本的含义 1 1.1 优化器选项 2 1.2 成本的定义 3 1.3 变换和成本计算 5 1.4 所见未必即所得 8 1.5 本章小结 8 1.6 测试用例 8 第2章 表扫描 9 2.1 入门 10 2.2 提高 14 2.2.1 块大小的影响 14 2.2.2 CPU成本计算 16 2.2.3 CPU成本计算的作用 22 2.3 BCHR 24 2.4 并行执行 27 2.5 索引快速全扫描 30 2.6 分区 32 2.7 本章小结 37 2.8 测试用例 37 第3章 单表选择率 39 3.1 入门 40 3.2 空值 42 3.3 使用列表 43 3.4 区间谓词 48 3.5 双谓词 52 3.6 多谓词的相关问题 54 3.7 本章小结 56 3.8 测试用例 57 第4章 简单B树访问 59 4.1 索引成本计算的基础知识 60 4.2 入门 61 4.2.1 有效索引选择率 63 4.2.2 有效表选择率 64 4.2.3 clustering_factor 65 4.2.4 综合计算 67 4.2.5 扩展算法 68 4.2.6 3个选择率 74 4.3 CPU成本计算 78 4.4 待处理的零碎问题 80 4.5 本章小结 81 4.6 测试用例 81 第5章 群集因子 83 5.1 基本示例 84 5.1.1 减少表争用 (多个自由列表) 86 5.1.2 减少叶块的争用(反转键 索引,ReverseKey Index) 89 5.1.3 减少表的争用(ASSM) 92 5.1.4 减少RAC中的争用 (自由列表群) 95 5.2 列顺序 96 5.3 额外的列 99 5.4 校正统计信息 101 5.4.1 sys_op_countchg()技术 101 5.4.2 非正式策略 105 5.5 待处理的零碎问题 106 5.6 本章小结 107 5.7 测试用例 107 第6章 选择率的相关问题 109 6.1 不同的数据类型 110 6.1.1 日期类型 110 6.1.2 字符类型 110 6.1.3 愚蠢的数据类型 112 6.2 前导零 116 6.3 致命的默认值 117 6.4 离散数据的风险 119 6.5 令人惊奇的sysdate 123 6.6 函数表示 125 6.7 相互关联的列 126 6.7.1 动态采样 129 6.7.2 优化器配置文件 132 6.8 传递闭包 133 6.9 产生约束的谓词 136 6.10 本章小结 139 6.11 测试用例 139 第7章 直方图 141 7.1 入门 142 7.2 普通直方图 147 7.2.1 直方图和绑定变量 147 7.2.2 Oracle何时忽略直方图 149 7.3 频率直方图 152 7.3.1 伪造频率直方图 155 7.3.2 注意事项 156 7.4 “高度均衡”直方图 157 7.5 重新审视数据问题 163 7.5.1 愚蠢的数据类型 163 7.5.2 危险的默认值 166 7.6 本章小结 167 7.7 测试用例 168 第8章 位图索引 169 8.1 入门 170 8.1.1 索引组件 174 8.1.2 表组件 175 8.2 位图合并 177 8.2.1 较低的基数 179 8.2.2 空值列 182 8.3 CPU成本计算 185 8.4 些有趣的示例 186 8.4.1 多列索引 187 8.4.2 位图连接索引 187 8.4.3 位图转换 188 8.5 本章小结 191 8.6 测试用例 192 第9章 查询变换 193 9.1 入门 194 9.2 过滤 197 9.2.1 过滤优化 200 9.2.2 标量子查询 202 9.2.3 子查询分解 208 9.2.4 复杂视图合并 213 9.2.5 推入谓词 215 9.3 般子查询 216 9.3.1 子查询参数 218 9.3.2 分类 219 9.3.3 半连接 224 9.3.4 反连接 226 9.3.5 反连接异常 228 9.3.6 Null和Notin 229 9.3.7 有序提示 231 9.4 星型变换连接 232 9.5 星型连接 237 9.6 展望 239 9.7 本章小结 240 9.8 测试用例 241 第10章 连接基数 243 10.1 基本的连接基数 244 10.2 实际SQL的连接基数 249 10.3 扩展和异常情况 252 10.3.1 使用范围的连接 252 10.3.2 不等于 253 10.3.3 重叠 256 10.3.4 直方图 257 10.3.5 传递闭包 260 10.4 三表连接 264 10.5 空值 267 10.6 实现问题 270 10.7 困难之处 274 10.8 特性 276 10.9 另观点 278 10.10 本章小结 279 10.11 测试用例 279 第11章 嵌套循环 281 11.1 基本机制 282 11.2 实际示例 286 11.3 完备性检查 287 11.4 本章小结 291 11.5 测试用例 291 第12章 散列连接 293 12.1 入门 294 12.1.1 最优散列连接 297 12.1.2 遍散列连接 299 12.1.3 多遍散列连接 304 12.2 追踪文件 308 12.2.1 event 10104 308 12.2.2 event 10053 309 12.3 难点 311 12.3.1 传统成本计算 311 12.3.2 现代成本计算 312 12.4 比较 313 12.5 多表连接 318 12.6 本章小结 321 12.7 测试用例 321 第13章 排序与归并连接 323 13.1 入门 324 13.1.1 内存的使用 329 13.1.2 CPU的使用 330 13.1.3 sort_area_retained_size 333 13.1.4 pga_aggregate_target 334 13.1.5 实际I/O 337 13.2 排序的成本 339 13.3 比较 343 13.4 归并连接 346 13.4.1 归并机制 347 13.4.2 无最初排序的归并连接 351 13.4.3 笛卡尔归并连接 352 13.5 聚集及其他 354 13.5.1 索引 358 13.5.2 集合运算 359 13.6 最后次提醒 363 13.7 本章小结 365 13.8 测试用例 366 第14章 10053 trace文件 367 14.1 查询 368 14.2 执行计划 369 14.3 环境 370 14.4 追踪文件 371 14.4.1 参数设置 372 14.4.2 查询块 375 14.4.3 存储统计信息 376 14.4.4 单表 378 14.4.5 完备性检查 379 14.4.6 般计划 380 14.4.7 Join order[1] 380 14.4.8 Join order[2] 386 14.4.9 Join order[3] 387 14.4.10 Join order[4] 388 14.4.11 Join order[5] 388 14.4.12 Join order[6] 392 14.4.13 Join order[7] 392 14.4.14 Join order[8] 395 14.4.15 Join order[9] 397 14.4.16 Join order[10] 398 14.4.17 Join order[11] 398 14.4.18 Join order[12] 401 14.4.19 Join order[13] 404 14.4.20 Join order[14] 405 14.4.21 Join order[15] 406 14.4.22 Join order[16] 407 14.4.23 Join order[17] 407 14.4.24 Join order[18] 409 14.5 连接评估小结 410 14.6 测试用例 413 附录A 升级问题 415 A.1 dbms_stats 416 A.2 频率直方图 417 A.3 CPU成本计算 417 A.4 舍入误差 417 A.5 绑定变量窥视 418 A.6 连接间的空值 418 A.7 B树到位图的转换 418 A.8 索引跳跃扫描 419 A.9 AND-Equal 419 A.10 索引散列连接 420 A.11 修正的In-List 420 A.12 传递闭包 420 A.13 sysdate算术修正 421 A.14 对空值的索引 422 A.15 pga_aggregate_target 422 A.16 排序 422 A.17 分组 423 A.18 完备性检查 423 A.19 超出界限的情况 423 A.20 关于类型 423 A.21 optimizer_mode 424 A.22 降序索引 424 A.23 复杂视图合并 424 A.24 非嵌套子查询 424 A.25 标量和过滤子查询 425 A.26 并行查询策略的两次变化 425 A.27 动态采样 425 A.28 临时表 425 A.29 字典统计 426 附录B 优化器参数 427 B.1 optimizer_features_enable 428 B.2 10053 trace文件 430 B.3 v$sql_optimizer_env 435
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值