2012-01-17 71 views
2

我有一個事件數據庫,每天晚上都會更新。單個事件包含三個(或更多)表中的信息。最近更新量已經導致我的MySQL引擎非常慢,直到我插入新事件時,其他查詢被凍結。爲了加快速度,我想進行一系列批量查詢,而不是分別執行每個批量查詢,而我認爲這是很大一部分開銷。棘手的MySQL批量查詢

的問題是,因爲數據在多個表傳播,這是我必須做的,插入一個事件:

(in Mysql) INSERT INTO 'locations' (...) VALUES (...) ON DUPLICATE KEY UPDATE ... 
    (in php get the last inserted id into variable $locationID) 
    (in Mysql) INSERT INTO 'event_info' (...) VALUES ($locationID, ...) ON DUPLICATE KEY UPDATE... 
    (in php get the last inserted id into variable $eventID) 
    (in Mysql) INSERT INTO 'event_times' (...) VALUES ($eventID, ...) ON DUPLICATE KEY UPDATE... 

我不是在設計表中尋求幫助,但你可以看到插入單個事件需要至少三個插入,每個插入取決於從前一個獲取id。這就是爲什麼我不知道從哪裏開始將其作爲批量請求。將這個過程設計成批量請求的任何幫助都會很棒,謝謝!

編輯:我可能已經有位置或事件信息之前,這就是爲什麼在上的重複密鑰更新的部分是有這樣,如果它已經在數據庫中,我得到舊的標識。我不知道,直到插入,如果它是新的數據,或者它已經存在於數據庫中。 (因爲這一點,除非我誤解,否則我不能做預先分配ID的事情,因爲每次都假設一個新ID。)

+0

你在使用什麼數據庫引擎?請記住,MyISAM爲每個插入鎖定表。 – 2012-01-17 22:30:41

+0

這是MyISAM,但其他​​查詢被凍結到一個完全不同的表,而不是這會影響,所以我認爲這只是所有插入和索引更新的整體應變。 – hackartist 2012-01-17 22:39:58

回答

2

不要使用自動遞增列 - 在插入前預先分配您的引用ID。這樣你可以使用批量插入並刪除依賴項。

更新:

  1. 選擇任何現有的ID從數據庫(理想的是單一選擇爲所有已知的數據)。

  2. 豐富數據以插入任何已知的ID。 (爲每個項目計算一個關鍵字,這些關鍵字將與數據庫中的表的主鍵相對應,使用該關鍵字更新數據庫中具有id的項目) - 您希望最終將數據拆分爲您知道的項目數據庫,因此有一個已知的ID - 和數據庫中不存在的數據,因此需要一個密鑰分配。我假設你的表有一個不僅僅是id的主鍵 - 否則數據庫如何知道你已經擁有數據庫中的數據。

  3. 將新ID分配給沒有ID的任何記錄。

  4. 批量替換數據庫中的數據(用單條語句插入多行)。

+0

有趣的是,我會怎麼做?問題是這個位置可能是我已經擁有的位置,並且直到ON DUPLICATED KEY UPDATE部分發生,我不知道它是否是新的或不是... – hackartist 2012-01-17 21:12:11

+1

將您的INSERT INTO更改爲REPLACE INTO - 然後它會自動更新當你的主鍵匹配時。 – 2012-01-17 21:29:33

+0

至於你的ID - 創建你自己的一種方法分配MySQL以外的唯一引用。 – 2012-01-17 21:30:37

2

不知道有關細節MySQL,但是這意味着任何有自尊的RDBMS有所謂的「序列」實體用作適合表主鍵唯一值的來源。

下面是使用序列解決您的問題的方法,這是我多次遇到的問題。使用僞代碼:

  1. 開始交易從某種序列
  2. 選擇3個一個值。同樣,任何自尊的RDBMS將保證每個「下一個序列值」的查詢都會返回唯一值,適合用作主鍵。三個選定的值將用於locations,event_info,event_times中新記錄的主鍵;
  3. 使用第1步的值執行INSERT INTO locations;
  4. 使用第1步的值執行INSERT INTO event_info;
  5. 使用第1步的值執行INSERT INTO event_times;
  6. COMMIT交易,如果一切順利的話。否則,交易爲ROLLBACK

在一次交易中使所有INSERT成爲必需。 爲了進一步增強,您可以批量查詢。

UPDATE之前符合您的有關數據可能前生要求INSERT小號

如果您更新報文總是包含完整的一組數據:也就是位置,event_info和event_times:上方。然後使用方法並刪除表中的舊記錄。這假定您可以使用SELECT舊實例使用主鍵以外的一些數據(即數據稱爲域級主鍵)。不要忘記在同一個交易中製作DELETE

+0

我該如何處理剛纔在EDIT中提到的問題,以解決我原來的問題? – hackartist 2012-01-17 21:16:41

+1

@hackartist更新了答案 – 2012-01-17 21:36:36

+0

謝謝,我投了你的答案。另一個答案在幾分鐘前提出,我使用REPLACE INTO,它會爲我刪除和插入,但如果他沒有先回答我會接受你的答案。謝謝。 – hackartist 2012-01-17 21:40:14