2012-10-30 64 views
0

基本上我的問題是,我有一個大約17,000,000種產品的大表,我需要應用一堆更新來真正快速。Mysql InnoDB和快速應用大型更新

該表有30列,id設置爲int(10)AUTO_INCREMENT。

我有另一個表格,這個表格的所有更新都存儲在這裏,這些更新必須預先計算,因爲他們需要幾天的時間來計算。該表的格式爲[product_id int(10),update_value int(10)]。

我正在採取的快速發佈這1700萬次更新的策略是,將所有這些更新加載到ruby腳本的內存中,並將它們分組到數組的散列中,以便每個update_value都是一個鍵,每個數組都是一個鍵已排序的product_id的列表。

{ 
    150: => [1,2,3,4,5,6], 
    160: => [7,8,9,10] 
} 

更新,然後在

UPDATE product SET update_value = 150 WHERE product_id IN (1,2,3,4,5,6); 
UPDATE product SET update_value = 160 WHERE product_id IN (7,8,9,10); 

格式出具我敢肯定,我在這個意義上正確地做這個是發佈關於PRODUCT_ID的能跟批次的更新應該是最佳方式用mysql/innodb來做到這一點。

我遇到了一個奇怪的問題,雖然當我測試更新~13萬條記錄時,這隻需要大約45分鐘。現在我正在測試更多的數據,約1700萬條記錄,並且更新時間接近120分鐘。我本來會期望某種速度在這裏下降,但不會達到我所看到的程度。

任何關於如何加快速度的建議或者可能會使這個更大的記錄集放慢速度的建議?

就服務器規格而言,它們非常好,內存/ CPU的堆,整個數據庫應該適合內存有足夠的空間來增長。

+1

您是否調整了您的innodb_ *設置,以利用您的「堆內存」優勢? – hexist

+0

是的,服務器傢伙有一個調整得相當好。 – Marklar

回答

0

您可以嘗試使用MySQL的多表更新語法

update product, sometable SET product.update_value=sometable.value WHERE product_id=sometable.whatever; 

這樣,它是一個單次通過數據庫和一個大的查詢MySQL能夠通過

0

磨我認爲你需要仔細設計索引和數據頁面訪問。

假設product_id s在查詢上的分佈是隨機的,每個更新SQL都會導致隨機索引頁訪問。當然,索引頁訪問之後的數據頁訪問也是隨機的。如果您希望所有更新都能夠快速運行,您需要在內存中至少有所有索引頁。因此,這不是一組快速更新操作。

如果我設計它和更新不被交易需要, 我會通過一個更新的所有行,一個,每product_ids這樣不在事務:

UPDATE product SET update_value = 150 WHERE product_id = 1 
UPDATE product SET update_value = 150 WHERE product_id = 2 
... 

,因爲它會導致索引頁面和數據頁面按順序讀取/更新,這種方案可能需要更長的更新時間,但從緩存管理的角度來看,這種方案要便宜得多。當然, 對數據庫的總體影響是最小的,因此除update之外的操作(如來自客戶的查詢)不會降級。

如果事務操作是一個需求,我可能想要有兩個表,或者使用一些技巧將兩個邏輯表合併到一個表中,這種表在上面的緩存討論的角度上更便宜。但是,如果您不需要交易,則需要按照product_id進行緩慢更新。