给定一个包含 CHAR(15) 类型的 A、B 和 C 列和唯一索引的表
如果我有一个带有指定 A 和 C 的 WHERE 子句的查询,oracle 的优化器会选择执行索引范围扫描。但是如果我知道 B 的基数很低,我应该提示 oracle 使用索引跳过扫描吗?跳过非前导列(在本例中为 B)是否会比范围扫描更高效?跳过扫描会跳过索引中的 A 和 B,还是只跳过 B?
给定一个包含 CHAR(15) 类型的 A、B 和 C 列和唯一索引的表
如果我有一个带有指定 A 和 C 的 WHERE 子句的查询,oracle 的优化器会选择执行索引范围扫描。但是如果我知道 B 的基数很低,我应该提示 oracle 使用索引跳过扫描吗?跳过非前导列(在本例中为 B)是否会比范围扫描更高效?跳过扫描会跳过索引中的 A 和 B,还是只跳过 B?
一般来说,优化器在确定范围扫描是否比跳过扫描更有效(反之亦然)方面要好得多。如果优化器做出了错误的选择,问题几乎总是归结为人类没有以表和索引的准确统计信息的形式向优化器提供正确的信息(包括包含倾斜数据的列上的直方图) )。
对于任何给定的查询,确定两个计划中哪一个更有效的唯一方法是在您的查询中使用您的硬件上的数据进行尝试。您可以尝试添加提示以强制更改计划,然后您可以衡量哪种方法实际上更有效。如果优化器选择的计划不是最有效的,我倾向于怀疑根本原因是统计数据的某些方面不正确,但您需要查看 10053 跟踪才能获得在大多数情况下到底部。很少有优化器出错的情况,因为优化器无法考虑数据的某些方面(例如,直到最近,car
make
, model
, 和year
知道一个值的列限制了其他列中的一组有效值)。