Mysql

分區是否有助於按主鍵查找和插入/更新?

  • June 27, 2017

我正在使用 MariaDB 10.1 和預設的 InnoDB 儲存,我有幾個表,目前有 10 到 1 億行。這些表每月將繼續增長幾百萬,而且主要是記憶體。

它們要麼有一個單列主鍵BIGINTBIGINT我還通過主鍵或選擇進行了很多連接WHERE PK IN (1, 2, 3, 4...)

此外,這些表每小時會收到很多更新,我通常一次更新 5000 或 10000 個。對於其中一些表,我們有比選擇更多的插入和更新。

我有3個問題:

  1. 在我看來,通過 PK 返回 1 行 ( SELECT x, y FROM table WHERE pk = 123) 進行的簡單選擇在分區性能上沒有實際差異。那正確嗎?
  2. join 或 select asWHERE PK IN(SELECT PK FROM ...)怎麼樣?它會導致更多的掃描加入分區表而不是單個表嗎?
  3. 考慮到我通常使用以下方法進行大量並發批處理(多個伺服器可能同時發送數據):
  • 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 ... )表現很差,某些情況下很差,應該避免。改用 a JOIN。對於分區,可能不會使用“修剪”。因此慢。

Q3:不管怎樣 INSERT,速度可能差不多。由於復雜性較低,普通表可能會更快。

Q3: REPLACEDELETE+ INSERTINSERT ... 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 到“真實”表中。

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