分區是否有助於按主鍵查找和插入/更新?
我正在使用 MariaDB 10.1 和預設的 InnoDB 儲存,我有幾個表,目前有 10 到 1 億行。這些表每月將繼續增長幾百萬,而且主要是記憶體。
它們要麼有一個單列主鍵
BIGINT
(BIGINT
我還通過主鍵或選擇進行了很多連接WHERE PK IN (1, 2, 3, 4...)
。此外,這些表每小時會收到很多更新,我通常一次更新 5000 或 10000 個。對於其中一些表,我們有比選擇更多的插入和更新。
我有3個問題:
- 在我看來,通過 PK 返回 1 行 (
SELECT x, y FROM table WHERE pk = 123
) 進行的簡單選擇在分區性能上沒有實際差異。那正確嗎?- join 或 select as
WHERE PK IN(SELECT PK FROM ...)
怎麼樣?它會導致更多的掃描加入分區表而不是單個表嗎?- 考慮到我通常使用以下方法進行大量並發批處理(多個伺服器可能同時發送數據):
INSERT INTO X VALUES (1, 'A'), (2, 'B'), ... ON DUPLICATE KEY UPDATE ...
要麼REPLACE INTO X VALUES(1, 'A'), (2, 'B'),...
分區是否有助於並發插入和更新,比如能夠同時影響多個分區?
提前致謝。
你的問題
Q1:如果 PK 是Partition key,則 Partition key 上的“點查詢”(
WHERE PK = constant
)將進行“修剪”,然後(希望)在它找到的單個分區中使用索引。與具有合適索引的簡單表相比沒有任何改進。Q1:如果 PK 是
PRIMARY KEY
,但不是Partition 鍵,則查詢必須打開並查看每個分區以查找行,因此速度較慢。Q2:一般
IN ( SELECT ... )
表現很差,在某些情況下很差,應該避免。改用 aJOIN
。對於分區,可能不會使用“修剪”。因此慢。Q3:不管怎樣
INSERT
,速度可能差不多。由於復雜性較低,普通表可能會更快。Q3:
REPLACE
是DELETE
+INSERT
。INSERT ... ON DUPLICATE KEY UPDATE ...
通常是更好的構造;看看它是否適用。但是,同樣,沒有性能改進。在
WHERE PK IN (1, 2, 3, 4...)
– 我想我聽說如果列表很短,它將使用分區修剪。或者如果列表很長,則跳過修剪。在任何一種情況下,一個帶有 PK 索引的簡單表至少會一樣快。修剪
以這種方式考慮修剪:首先它必須找到分區(其行為非常類似於“子表”),然後它必須使用索引(如果可用)向下鑽取到所需的行。沒有分區,它會跳過剪枝步驟;但 BTree 索引稍微深一些。所以這是一個權衡。
注意:這通常意味著分區表和等效的非分區表的最佳索引集是不同的。
案例3
警告“表的索引太大而無法記憶體,但一個分區的索引是可記憶體的”似乎不適用於您的情況。案例 3 來自一個時間序列,其中大部分活動都在最新的分區 (and
PARTITION BY RANGE(TO_DAYS(...))
) 中,並且該分區適合 buffer_pool 但整個表沒有。(也就是說,關於案例 3 的相關性,我同意 Natan 而不是 Jarwad。)
通過雜湊
BY HASH
- 沒有用。(來自連結:“PARTITION BY RANGE 是唯一有用的方法。”)(或者至少,我還沒有看到性能受益的雜湊案例。)攝取
“每月增長幾百萬”這不是很快。“每天增長幾百萬”將開始具有挑戰性,此時我將向您指出我的高速攝取部落格。即便如此,您可能會從那裡得到一個提示——將更改載入到臨時表中,然後從它插入/替換/iodku/update/etc 到“真實”表中。