2012-06-06 71 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

相關問題