在 oracle 中使用两个索引中的哪一个来评估此查询?
which of two indexes be used to evaluate this query in oracle?
我在学习索引概念时感到困惑,
例如:我有这个简单的查询
select productId,productName from product where productId='11107' and productName='Watch';
而且product很大table,productId和productName是product的两个属性table,11107和Watch是两个值
假设 1000 条记录满足条件,我考虑 productId 的主索引和 productName 的二级索引
productId='11107' 50条记录满足条件 productName='Watch' 每个数据页可存储100条记录
随机IO的开销是顺序IO的10倍I/O.
现在使用两个索引中的哪一个来评估此查询?
解决方案:
按我的理解应该是主索引因为主索引属性"productId" returns多条记录在这里说1000,
与二级索引属性 "productName" 相比,后者 returns 只有 50 条记录。
另外,由于每个数据页存储 100 条记录,因此对于主索引,我们需要 10 页,对于二级索引,我们需要 1 页。
由于 table ""product" 非常大所以只有较少的记录说 50 条满足顺序访问的条件(一次扫描一条记录)。
我的评价是正确的还是有什么需要补充的。有什么建议么。
Oracle在评估最佳执行计划时会考虑很多因素。
- 索引类型(唯一、正常等)
以下来自 dba_indexes 视图的统计数据
LEAF_BLOCKS
DISTINCT_KEYS
CLUSTERING_FACTOR
NUM_ROWS
例如,对于相同的条件,Oracle 为 DISTINCT_KEYS 更接近 NUM_ROWS
的索引提供较低的成本
在您的情况下,假设两者都是普通索引并且所有统计信息都是最新的 - 具有更多不同键的索引可能比另一个更受欢迎。
如果我没有理解错的话,你的基本逻辑似乎是倒退的。您似乎是说将使用主索引,因为它会 return 更多行,这与基本经验法则相反 - 通常首选 selective 索引。
但是,您逻辑中的另一个潜在缺陷是:
as each datapage stores 100 records then for primary index we need 10
pages and for secondary index 1 page
你应该说 "between 10 and 1000" 和 "between 1 and 50"。仅仅因为 n 记录可以放入单个 "datapage"(或块,在 Oracle 术语中)并不意味着任何 n 记录你正在寻找实际上会在同一个街区。在您的示例中,10 个块是容纳 1000 行的最小值;但是给定 productId 的 1000 行实际上可能位于 1000 个不同的块中。 (假设 table 的大小至少为 1000 个块。)
问题不在于每个索引有多少行 return ("row selectivity"),而是有多少不同的块 这些行位于 ("block selectivity)。优化器使用每个索引的 CLUSTERING_FACTOR 值来估计行和块 selectivity 与一个索引的匹配程度另一个;低聚类因子通常意味着更好的块 selectivity.
有点超出您的问题范围,优化器也完全有可能既不使用索引,也不使用两者。
在某些时候,扫描索引(也需要 I/O)然后读取相应的 table 块所需的工作量可能比简单地读取整个 table。同样,CLUSTERING_FACTOR 和其他统计数据也影响了这个决定。
在某些情况下,包括您的示例,优化器也可能选择对两个索引进行扫描并通过 ROWID 值连接生成的索引条目,而无需访问 table 块全部。这是可能的,因为查询只使用索引中的列;如果您在 select 列表中添加了另一列,则查询必须读取 table 块才能获取该数据。
我在学习索引概念时感到困惑,
例如:我有这个简单的查询
select productId,productName from product where productId='11107' and productName='Watch';
而且product很大table,productId和productName是product的两个属性table,11107和Watch是两个值
假设 1000 条记录满足条件,我考虑 productId 的主索引和 productName 的二级索引
productId='11107' 50条记录满足条件 productName='Watch' 每个数据页可存储100条记录
随机IO的开销是顺序IO的10倍I/O.
现在使用两个索引中的哪一个来评估此查询?
解决方案:
按我的理解应该是主索引因为主索引属性"productId" returns多条记录在这里说1000, 与二级索引属性 "productName" 相比,后者 returns 只有 50 条记录。
另外,由于每个数据页存储 100 条记录,因此对于主索引,我们需要 10 页,对于二级索引,我们需要 1 页。
由于 table ""product" 非常大所以只有较少的记录说 50 条满足顺序访问的条件(一次扫描一条记录)。
我的评价是正确的还是有什么需要补充的。有什么建议么。
Oracle在评估最佳执行计划时会考虑很多因素。
- 索引类型(唯一、正常等)
以下来自 dba_indexes 视图的统计数据
LEAF_BLOCKS
DISTINCT_KEYS
CLUSTERING_FACTOR
NUM_ROWS
例如,对于相同的条件,Oracle 为 DISTINCT_KEYS 更接近 NUM_ROWS
的索引提供较低的成本在您的情况下,假设两者都是普通索引并且所有统计信息都是最新的 - 具有更多不同键的索引可能比另一个更受欢迎。
如果我没有理解错的话,你的基本逻辑似乎是倒退的。您似乎是说将使用主索引,因为它会 return 更多行,这与基本经验法则相反 - 通常首选 selective 索引。
但是,您逻辑中的另一个潜在缺陷是:
as each datapage stores 100 records then for primary index we need 10 pages and for secondary index 1 page
你应该说 "between 10 and 1000" 和 "between 1 and 50"。仅仅因为 n 记录可以放入单个 "datapage"(或块,在 Oracle 术语中)并不意味着任何 n 记录你正在寻找实际上会在同一个街区。在您的示例中,10 个块是容纳 1000 行的最小值;但是给定 productId 的 1000 行实际上可能位于 1000 个不同的块中。 (假设 table 的大小至少为 1000 个块。)
问题不在于每个索引有多少行 return ("row selectivity"),而是有多少不同的块 这些行位于 ("block selectivity)。优化器使用每个索引的 CLUSTERING_FACTOR 值来估计行和块 selectivity 与一个索引的匹配程度另一个;低聚类因子通常意味着更好的块 selectivity.
有点超出您的问题范围,优化器也完全有可能既不使用索引,也不使用两者。
在某些时候,扫描索引(也需要 I/O)然后读取相应的 table 块所需的工作量可能比简单地读取整个 table。同样,CLUSTERING_FACTOR 和其他统计数据也影响了这个决定。
在某些情况下,包括您的示例,优化器也可能选择对两个索引进行扫描并通过 ROWID 值连接生成的索引条目,而无需访问 table 块全部。这是可能的,因为查询只使用索引中的列;如果您在 select 列表中添加了另一列,则查询必须读取 table 块才能获取该数据。