2012-06-06 44 views
1

目前,我正在做一些测试,我注意到以下几点:为什么选择比非索引列更快的pk列?

select field1 from table1 

会导致成index fast full scanfield1是主键,从而以较低的成本(在我的情况下,它是)而

select field2 from table1 

会导致成table access full(有没有约束,也没有指数field2然而,即使有正规指数结果是一样的),与费用为。

我知道在JOIN/WHERE子句中涉及索引/约束时的增益,但在我的情况下没有任何过滤:我不明白为什么PK应该更快,因为,无论如何,I正在检索全部的行...

是因为唯一性吗?汤姆说,一个unique index is the same as a conventional index, structurally,这真的让我想知道为什么选择PK将比其他任何列成本低。

感谢您的启示:-)

rgds。

回答

4

单列b-tree索引不存储空值行的数据。因此,如果您有field2上的索引,但field2允许NULL,则Oracle无法对索引执行扫描,而没有可能返回错误数据的风险。因此,全表扫描是Oracle检索table1中每行的field2列的唯一有效方式。如果将约束条件NOT NULL添加到field2,Oracle应该至少可以考虑对索引进行全面扫描。

当然,优化程序是否选择使用索引(以及它最终使用索引分配的成本)取决于您在索引和表上收集的统计信息。如果您的统计信息不准确,优化程序的成本估算将不准确,因此生成的计划可能效率不高。这就是人们通常建议谨慎对待Oracle对计划成本估计的谨慎态度的原因之一 - 如果您正在查看计划,很可能是因为您怀疑这种计划效率低下,这应该意味着你不能依靠成本。您通常会更好地查看每个步骤的基数估计值,并根据您的数据分布确定这些估计值是否有意义。

+0

我明白了,谢谢。所以你的意思是说,任何非空列,没有索引,应该给我和我在例子中使用的简单选择的上下文中的PK选择一样的好结果? – Sebas

+0

@Sebas - 如果该列被声明为'NOT NULL'并且该列上有索引,则您应该获得相同的性能,因为Oracle可以通过从索引中读取数据而不需要击中表来满足查询。 –

+0

我仍然感到困惑,因为索引没有加载到内存或类似的东西中,如果行被索引或者没有索引,如何返回所有行更快?如果我们必须分类,请加入...好吧,但只是检索数据,残酷地说,它是如何变得更快? – Sebas

相关问题