2012-02-07 60 views
1

我有一個刮板,它訪問許多網站,並發現即將發生的事件和另一個腳本實際上應該把它們放在數據庫中。目前插入數據庫是我的瓶頸,我需要一個更快的方式來批量查詢,而不是我現在擁有的。棘手的MySQL批處理設計

是什麼讓這個棘手的是,一個單一的事件有三個表中的數據,它們之間有相互的鍵。要插入單個事件,我插入位置或獲取該位置的已經存在的ID,然後插入實際的事件文本和其他數據,或者獲取事件ID(如果它已存在的話)(某些重複每週等),最後插入日期與位置和事件id。

我不能使用REPLACE INTO,因爲它會使用這些相同的密鑰來隔離較舊的數據。我在Tricky MySQL Batch Query問過這個問題,但是如果TLDR的結果是我必須檢查哪些鍵已經存在,請預先分配那些不存在的,然後爲每個表做一個插入(即在php中完成大部分工作)。這很好,但問題是,如果一次處理多個批次,他們可能會選擇預先分配相同的密鑰,然後相互覆蓋。無論如何,因爲那麼我可以回到這個解決方案嗎?批次必須能夠並行工作。

我現在所擁有的只是關閉批處理持續時間的索引並分別插入每個事件,但我需要更快的一些事情。任何想法都會對這個棘手的問題有所幫助。 (這些表是InnoDB現在...可以交易幫助解決這一切?)

回答

1

我建議從Mysql Lock Tables開始,您可以使用它來防止其他會話在插入數據時寫入表中。

例如,你可能會做同樣的事情到這個

mysql_connect("localhost","root","password"); 
mysql_select_db("EventsDB"); 
mysql_query("LOCK TABLE events WRITE"); 
$firstEntryIndex = mysql_insert_id() + 1; 
/*Do stuff*/ 
... 
mysql_query("UNLOCK TABLES); 

上面做了兩兩件事。首先,鎖定表格,阻止其他會話寫入,直到完成並解鎖語句運行。第二件事是$ firstEntryIndex;這是將在任何後續插入查詢中使用的第一個鍵值。

+0

嗯,這肯定會解決數據能夠相互覆蓋的問題,但是整個目標是讓所有事情都變得更快,因此一次只限制一個進程似乎是退步了。 – hackartist 2012-02-07 19:36:09

+0

它不會將進程限制爲單個實例,只要確保您可以基於單個密鑰進行處理而不會有數據丟失/損壞的風險。您使用哪種方法不可能在不影響效率的情況下爲鎖表的預處理和安全性提供靈活性。 – CBusBus 2012-02-07 19:53:08