Oracle

具有數百萬個不同值的索引列是否有意義?

  • May 29, 2017

我注意到我的一個查詢非常慢,大約需要兩秒鐘才能執行。

這是慢查詢:

SELECT EVENT_DATETIME, EVENT_EVENTTYPE FROM EVENT WHERE (EVENT_ID = :1  AND EVENT_RESULT = :2  )

使用的索引是這樣創建的:

CREATE INDEX "INDEX_EVENT_DATETIME" ON "EVENT" ("EVENT_DATETIME", "EVENT_ID")

執行計劃顯示一個index skip scan因為顯然該EVENT_DATETIME列不在 where 子句中。

所以起初我以為我會在表上為列創建第二個連接索引,(EVENT_ID, EVENT_RESULT)但後來我注意到該列EVENT_DATETIME有 18,702,145 個不同的值。共有 18,722,706 行。

此表上定期發生 4 個不同的查詢。除了一個之外,它們都在 where 子句中具有EVENT_DATETIME列,但它們都EVENT_ID在 where 子句中。

所以我的假設是目前使用的索引不會使查詢更有效率。

列上的連接索引(EVENT_ID, EVENT_DATETIME是否更有用?

對於 b-tree index ,不同的值越多越好。

在您的情況下,索引跳過掃描似乎不是一種有效的訪問方法,因為索引中的第一列具有高基數。它與“正常”索引使用相反,如索引範圍掃描或索引唯一掃描,您希望第一列最具區分性。很難說在這種特殊情況下,全表掃描是否會在不嘗試的情況下表現得更好(FULL或者NO_INDEX提示可以完成這項工作)。

毫無疑問,對於有問題的查詢 index onevent_id,event_date比 on 好得多event_date,event_id

如果沒有看到您的其他查詢,很難判斷,但我認為您可能不一定需要有復合索引。每列 event_date 和 event_id 似乎都很少有重複項(如果有的話)。然後擁有兩個索引,一個一個一個EVENT_DATE,另一個打開EVENT_ID比擁有多個連接索引更好 - 即使復合索引覆蓋了某些查詢,引擎也只需要做一兩個額外的查找。

具有數百萬個不同值的索引列是否有意義?

當然,為什麼不呢?主鍵索引不會對每一行都有不同的值嗎?即使基礎列具有大量不同的值,查詢的覆蓋索引仍然很有用。在進行範圍掃描時,此類索引也很有用。如果您想要一天的所有數據,那麼我不明白為什麼有多少不同的值很重要。

所以我的假設是目前使用的索引不會使查詢更有效率。

EXPLAIN PLAN 顯示正在使用的索引。這意味著 Oracle 查詢優化器認為索引使查詢更有效率。如果您認為這不正確,請嘗試使用NO_INDEX 提示測試查詢。它的效率更高還是更低?

列(EVENT_ID,EVENT_DATETIME)上的連接索引是否更有用?

您在問這個問題,但您沒有向我們提供有關其他列的查詢或任何統計資訊。您能做的最好的事情就是嘗試測試不同的選項。為什麼在不需要的時候猜測?創建多個索引並查看 Oracle 使用哪個索引。NO_INDEX如果您真的想查看查詢的差異,請根據需要使用提示。綜上所述,如果該EVENT_ID列的選擇性比EVENT_DATETIME那麼您的其他建議索引可能對問題中的查詢更有用。

引用自:https://dba.stackexchange.com/questions/174816