全局索引

 

目錄

索引表相關介紹

單機表索引:

本地分區索引(Local Partitioned Index):

全局非分區索引(Global Non-Partitioned Index)

全局分區索引(Global Partitioned Index)

分佈式場景下全局索引和本地索引的對比優勢

本地索引唯一性約束

掃描開銷:

全局索引優勢:

全局分區索引的實現方案

面臨的問題


索引表相關介紹

單機表索引:

本地分區索引(Local Partitioned Index):

 

全局非分區索引(Global Non-Partitioned Index)

全局分區索引(Global Partitioned Index)

索引的分區模式是完全獨立的,和主表的分區沒有任何關係,因此對於每個索引分區來說,裏面的某一個鍵都可能映射到不同的主表分區(當索引鍵有重複值時),索引分區和主表分區之間是“多對多”的對應關係。

employee表按照emp_id做了範圍分區,同時在emp_name上做了全局分區索引。可以看到同一個索引分區裏的鍵,會指向不同的主表分區。類似兩張相關聯的表,後面會提到數據更新的一致性問題。

由於全局索引的分區模式和主表的分區模式完全沒有關係,看上去全局索引更像是另一張獨立的表,因此也會將全局索引叫做索引表

分佈式場景下全局索引和本地索引的對比優勢

本地索引唯一性約束

本地索引只能在一個主表分區內保證索引鍵的“唯一性約束”,無法在全表範圍內保證索引鍵的唯一性約束

 

有些數據庫在分區表中會增加限制,要求主鍵和唯一索引的定義中必須包含主表所有的分區鍵字段。有了這個限制,索引中的某一個鍵所對應的索引數據只可能存在於一個分區中,因此只要在每一個分區內保證唯一性約束,即可在全表範圍內保證唯一性約束。

大大增加了開發人員的煩惱,因爲它會導致主鍵和唯一索引的可選範圍大大縮小(只能是主表分區鍵的“超集”),很多業務需求因此無法滿足,這也是本地索引最被詬病的地方。

掃描開銷:

某一個索引鍵值在所有分區的本地索引上都可能存在,任何索引掃描必須在所有的分區上都做一遍,以免造成數據遺漏。

這會導致索引掃描效率低下,並且會在全局範圍內造成CPU和IO資源的浪費。採用“分區間並行”的手段可以提高效率,但不能從根本上解決這個問題

比如分成1024片,那麼要掃描1024分片表對應的索引表。類似join。一個是3層*1024,一個是4層*1

 

全局索引優勢:

對於全局索引來說,可以爲索引數據指定自己的分區方式,並且索引的分區鍵一定是索引鍵的子集,對於某一個索引鍵來說,由於包含了所有的索引分區鍵,它的數據只可能落在一個固定的索引分區中,因此只要在每一個索引分區內保證唯一性約束,就可以在全表範圍內保證唯一性約束。而單個索引分區內只有一個索引數據結構,很容易保證唯一性約束,因此問題就得到了解決。

 

全局索引能保證某一個索引鍵的數據只落在一個固定的索引分區中。對於索引鍵值的範圍掃描,我們希望索引掃描按單向順序在每個分區內都只執行一次,而不必在索引分區之間來回穿梭,因此我們要求索引的分區鍵是索引鍵的“前綴(Prefix)”:比如索引鍵是”a,b”,那麼索引的分區鍵可以是”a”或者”a,b”,但不能是”b”,即要求分區的排序規則和索引樹的排序規則一致。這樣一來,無論是針對固定鍵值的索引掃描,還是針對一個鍵值範圍的索引掃描,都可以直接定位出需要掃描的一個或者幾個分區,而不是像本地索引一樣盲目地在所有分區上掃描,這樣就解決了本地索引面臨的問題。

全局索引也面臨一些問題,主要是架構複雜,實現難度大,以及由此引發的一些相關問題,比如當索引數據和對應的主表數據位於不同的機器時,在事務內會面臨數據一致性和性能方面的挑戰。但考慮到全局索引給數據庫使用者帶來的巨大便利,付出一點代價也是值得的

本地索引和全局索引的適用場景是不一樣的:

本地索引比較適合“索引鍵包含主表所有的分區鍵字段”這種特殊情況。

除了上面的特殊情況之外的其它場景,全局索引更加合適。

可以說,全局索引具有更強的通用性。

 

全局分區索引的實現方案

面臨的問題

每一個主表分區和索引分區都可能分佈在不同的機器上,比如“N個主表分區+M個全局索引分區”這種多對多的複雜情況,可能是(N+M)臺物理機器上形成的(N*M)種索引鍵到主表分區的映射關係,這會帶來諸多挑戰:

  • 如果一個事務中要修改的N條記錄分別位於N臺不同的機器上,而它們對應的全局索引數據又位於另外M臺不同的機器上,如何在這(N+M)臺機器間保證主表數據和索引數據的同步更新?

  • 還是上面所說的主表數據和索引數據分佈在不同機器的場景,在保證數據一致性的前提下,如何進一步縮短跨機器訪問的時間,進一步提高查詢效率?

  • 如何保證全局索引數據在全局範圍內的讀寫一致性?一臺機器上更新的索引數據,如何確保一定能被其它機器上後續的訪問者讀到?

解決方案

問題1-方案

如何保證主表數據和索引數據的跨機器同步更新。這個問題的本質,其實是分佈式數據庫中“分佈式事務一致性”問題,主表數據和索引數據是同一個事務中的兩部分數據,當它們分佈在不同的機器上時,分佈式事務需要保證事務的原子性(Atomicity):兩部分數據要麼全部更新成功,要麼全部失敗,不會因事務異常而導致主表數據和索引數據的不同步。

問題2-方案

索引數據和主表數據分跨機器訪問時的效率問題。這裏面臨的最大挑戰就是分佈式事務的網絡延遲和多次日誌落盤,而這種物理開銷是沒有辦法完全消除的,爲此Google在F1的論文中明確說明不推薦太多的全局索引,並且應儘量避免對有全局索引的表做大事務訪問。

問題3-方案

最後一個問題,則是分佈式數據庫中全局(跨多臺機器)的讀寫一致性問題。實現了快照隔離級別(Snapshot Isolation)和多版本併發控制(MVCC)的分佈式數據庫來說,如何在機器間有時鐘差異的情況下,仍能維持時間戳(即版本號)在全局範圍內的前後一致性,這是一個很重要的問題。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章