Index

為什麼 Cassandra 建議不要在高基數列上創建索引?

  • November 27, 2020

Cassandra 文件指出,

在這些情況下不要使用索引:

  • 在高基數列上,因為您隨後查詢大量記錄以獲得少量結果。請參閱下面的使用高基數列索引的問題。

它繼續,

如果您在具有許多不同值的高基數列上創建索引,則欄位之間的查詢將導致針對很少結果的多次搜尋。在包含 10 億首歌曲的表中,按作者(每首歌曲通常唯一的值)而不是按他們的藝術家查找歌曲可能效率很低。將表手動維護為索引形式而不是使用 Cassandra 內置索引可能會更有效。對於包含唯一數據的列,有時為了方便起見使用索引在性能方面很好,只要對具有索引列的表的查詢量適中並且不是處於恆定負載下。

但從來沒有真正回答過這個問題:為什麼它效率低下?我不知道“手動將表維護為索引的形式”是什麼意思。但是它有點自相矛盾,“……只要查詢量適中,使用索引有時在性能方面很好……”

這只是想告訴我何時何地可以使用PK嗎?什麼是低效率?我的理解是,會命中索引的查詢需要查詢集群中的每個¹節點,然後每個節點都會在其本地索引中進行查找,然後將結果匯總。這不一定很昂貴(每個索引查找應該相當便宜),除了我們支付網路延遲,因為我們必須等待批次中最慢的節點。我在這裡錯過了什麼嗎?

但是,如果我有一個包含 bajillion 項目的集合——在極少數情況下——需要通過不同但幾乎獨特的屬性進行查找……這是一個合適的用途,對嗎?

¹每個?IDK,如果複製意味著這可以達到集群的 1/3,複製因子為 3?

使用 Cassandra 索引(“二級索引”,而不是主鍵),每個節點都必須查詢自己的本地數據以響應查詢(請參閱 Cassandra二級索引常見問題解答)。這些索引也是使用後台程序建構的。這種背景意味著索引可能會返回命中的誤報(或未命中的誤報)。

這意味著在高基數列中,該列的變化率(添加/刪除)可能非常高。因此,如果該變化率比通過後台程序更新索引更快,那麼使用索引是“低效的”(索引執行的工作比應用程序所需的要多,這可能經常得到錯誤的答案) .

就查詢準確性而言,一種更有效的方法可能是維護第二張不是二級索引。與索引相反,表的處理方式與任何其他表一樣。它們更有可能為您的應用程序提供它所期望的查詢結果。缺點是維護表作為索引,而不是 Cassandra “二級索引”,現在是應用程序約束(,您的應用程式碼現在必須知道從該“索引”表中插入/刪除行,並且通過應用程序級別的“協調”使兩個表保持同步)。

希望這可以幫助!

一些術語:父表是在其上創建索引的表。二級索引表是為維護另一個表的索引而創建的表。

二級索引表的數據與父表的數據儲存在同一個節點上。Cassandra 分區程序不分區和分發索引表數據。因此,如果要對索引列執行查找,將查詢所有節點,而不僅僅是包含數據的副本節點。(協調節點不知道數據在哪裡)https://www.datastax.com/dev/blog/cassandra-native-secondary-index-deep-dive

對於 ssn 或其他一些唯一 id 等高基數列,將與主鍵進行一對一的映射。如果在此類列上創建索引,則數據駐留在節點的複制因子數上,但在所有節點上執行查找呼叫。在最好的情況下,協調器直接點擊包含數據的節點,一旦滿足一致性級別,您就會得到結果。最糟糕的是,如果您要查找的數據不存在於索引中,您將等到所有節點響應時才發現數據不存在。因此,對於二級索引表的每次查找呼叫,所有節點都會被命中。如果表是普通的 C* 表,則每次查找呼叫只命中節點的複制因子數。

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