[英]Partition MySQL table with primary key and concatonated unique index
[英]MySQL partition and unique key
我們有一個這樣的表來保存每個用戶會話的登錄令牌。 對該表進行了早期分區,但現在我們決定對其進行分區以提高性能,因為該表包含數百萬行。
CREATE TABLE `tokens` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`uid` int(10) unsigned DEFAULT NULL,
`session` int(10) unsigned DEFAULT '0',
`token` varchar(128) NOT NULL DEFAULT '',
PRIMARY KEY (`id`),
UNIQUE KEY `usersession` (`uid`,`session`),
KEY `uid` (`uid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 PARTITION BY HASH(id) PARTITIONS 101;
我們計划基於“ id ”進行分區,因為它主要用於“ select ”查詢,因此可以有效地執行修剪。
但是問題是我們維護(uid,session)的唯一索引,並且分區要求參與列成為唯一索引的一部分。 現在,在這種情況下, (id,uid,session)的唯一索引沒有意義(始終是唯一的)。
有沒有解決此問題而無需手動檢查(uid,會話)的方法。
大概您唯一的uid,sessionkey
索引為您實施了一些業務規則。
您是否依賴DBMS執行該規則? 您是否使用INSERT .... ON DUPLICATE KEY UPDATE...
語句,或使用錯誤處理程序或類似的方法來處理這種唯一性? 還是只是為了好措施?
如果您依賴該唯一索引, 則無法在id
上對該表進行分區。 Fugeddaboudit。
如果可以刪除該索引或刪除其唯一約束,則可以繼續進行分區。 但是分區通常不適用於具有多個唯一鍵的表。
通常,40M行的表不夠大,無法很好地進行分區。 如果您遇到性能問題,則應該研究改進索引。
編輯 :如果您擁有現代化的硬件(多TB存儲,足夠的RAM)和精心選擇的索引,則分區(我認為)是值得解決的更多麻煩。 對於少於約10 ** 9行的表,這肯定會帶來很多麻煩。 當您的自動遞增id
值必須為BIGINT
而不是INT
數據類型時(因為int.MaxValue不夠大),那么分區開始值得考慮。
當所有查詢都基於分區鍵進行過濾時,這是最有效的。 沒有分區鍵的其他條件上的篩選速度很慢。
專家提示:關於正則表達式的古老說法也適用於分區。 如果您解決了分區問題,那么現在有兩個問題。
BY HASH
可以加速系統的情況。 PRIMARY KEY
上分區幾乎幾乎沒有用。 (uid, session)
-- (uid, session)
時,不要使用AUTO_INCREMENT
id。 還是應該(toke n)
? (uid)
是多余的,給定(uid, session)
。 token
是base64,則將其ascii
或其他名稱。 因此,我認為這會更好地工作(更小,更快等):
CREATE TABLE `tokens` (
`uid` int(10) unsigned DEFAULT NULL,
`session` int(10) unsigned DEFAULT '0',
`token` VARBINARY(128) NOT NULL DEFAULT '',
PRIMARY KEY (token),
) ENGINE=InnoDB
您搜索哪個?
WHERE token = ...
WHERE uid = ... AND session = ...
缺點之一是我擺脫了id
; 如果其他表需要id
則需要在其中進行更改。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.