2012-12-06 44 views
3

我有一個基於InnoDB的模式,大概有100個表,大多數使用GUID/UUID作爲主鍵。我在一個時間點開始了這個工作,我並不真正瞭解UUID PK對於磁盤IO和碎片的影響,但希望在處理服務器集羣時避免使用單個密鑰分發器。我們目前沒有處理大量的行,但我們會(數以億計),我想爲此做好準備。使用GUID/UUID鍵優化Innodb表索引

既然我更好地理解了InnoDB中的索引,特別是主鍵的集羣特性,我可以看到我的UUID對於從DISK IO角度來看的可伸縮性來說是一個糟糕的選擇,但我不想停止使用它們由於服務器集羣要求。

接受/推薦的解決方案似乎是Autoincrement PK(INT | BIGINT)和UNIQUE Indexed UUID鍵的混合。我的目的是到一個新的第一列ai_col添加到每個表並將其指定爲新的PK,我正在隊列來源:

http://dev.mysql.com/doc/refman/5.1/en/innodb-auto-increment-handling.html

我會再更新/重新創建一個新的「獨特的」指數我的UUID鍵並繼續在我們的應用程序層使用它們。

我的期望是,一旦完成,我基本上可以忽略ai_col和其他一切照常運行。 InnoDB將有一個相對較小的基於int的PK,從中聚集並附加到其他唯一索引。

問題1:我是否正確地認爲,在這種新的情況下,我可以吃我的蛋糕,吃嗎?

後續問題是關於較小的「關聯」表,即只有兩列,其他表的外鍵隱式連接它們。在這些情況下,我通常有兩個索引,其中一個是UNIQUE的兩列索引,首先使用的是較多的列,然後是另一列的第二個索引。我知道這基本上是實際行數據的2.5倍,但它似乎確實有助於我們在優化期間更復雜的查詢,並且在較小的表上,因此相對可接受。

這些關聯表中的大多數只會是主表中記錄數的一小部分,因爲它們通常更具體,但是,在少數情況下這些關聯表具有許多倍數作爲其外部父母的記錄數,即潛在的數十億美元。

問題2:將數字PK添加到這些表中是否是一個好主意?我猜測答案會沿着「Benchtest」的方向發展,但我只是在尋找有用的智慧塊。

如果我明顯誤解了任何東西,或者您可以提供我可能沒有考慮的見解,我也會非常感激!

非常感謝!


編輯:正如在回答答應了,我只是想跟進興趣的人......這個解決方案有句名言工作:)讀寫性能全面提高,到目前爲止,它已經測試了約60億I/O /月,沒有打破汗水。

+0

它已經有一段時間了,我很好奇這是如何解決的。你是否需要做任何改變,你是否仍然能夠處理負載? – John

+0

@John嘿!與我們存儲的數據相比,空間要求可以忽略不計,因此這根本不是問題。最終通過適當的索引,這與任何僅使用AI列的解決方案一樣好,但具有UUID的所有優點。我們開始做的另外一件事情是將UUID存儲在BINARY(16)而不是CHAR(32)中,並使用'HEX()'和'UNHEX()'進行轉換。最小的開銷和一半的空間。 – oucil

+0

@John還有一個想法,我已經看到其他解決方案提出了調整UUID的結構,以便UUID的第一部分是基於時間的,從而避免了插入後重建/求助表的問題以及相應的高IO大型表,但是這樣會消除在BINARY中存儲的能力,因此您不會獲得上面提到的空間優化,並且需要額外的工作來編寫UUID驗證腳本,因爲它不再與內置機制兼容。他們可能仍然工作得很好,但我認爲這種方法更符合邏輯和標準。 – oucil

回答

1

如果沒有任何其他建議,確認或其他方式,我已經開始在我們的開發服務器上測試一些較少使用的表,但是如果新的基於AI的ID會影響我們應用程序層。

到目前爲止,它看起來不錯,索引按預期執行,並且新表字段不需要對應用程序層進行任何更改,但我們基本上可以忽略它們。

雖然在重負載下測試實際的磁盤IO,但是從主題信息的絕對數量來看,我還沒有進行任何徹底的工作臺測試,我可以推測我們的擴展能力很好。

一旦這已經到位了一段時間,我會放下後續的情況下,如果有人在同一條船,我們是。