2013-05-20 61 views
3

我有約會的網站。在這個網站,我用每天10場比賽的照片發送給用戶,並將其儲存在結構正在處理刪除/插入/選擇一個巨大的表格

SENDER RECEIVER 
11  1 
12  1 
13  1 
14  1 

我保持2個月日誌。 用戶也可以通過登錄到我的網站進行檢查。

這意味着有並行插入和選擇,這肯定不是問題。

問題是當用戶變爲非活動狀態或刪除其ID時,我需要從日誌中刪除所有條目,其中sender ='inactive-id'。

日誌大小約爲6000萬。 因此,無論何時刪除查詢進來這個巨大的表,所有選擇被鎖定,我的網站正在關閉。

注意我的表是因爲我需要儲存2-3個月的記錄,並在每個月的第一個改變我的定義

+0

你使用MyIsam引擎嗎? – Stephan

+0

@Stephan在這種情況下我目的如下的東西合併的myisam – chicharito

+0

:使用InnoDB發動機因爲其具有的行級鎖定(在插入和選擇將並行工作而不阻塞彼此)和分區表等Moby04建議 – Stephan

回答

3

通常,表是由DELETE語句鎖定的最細粒度的對象。因此,通過使用MERGE表,您可以將幾個可以獨立鎖定的對象合併到一個將被鎖定的大對象中,當DELETE遇到任何表時。

MERGE是一種很少或從不變的表格解決方案:MERGE Table Advantages and Disadvantages

你有2種選擇:

儘量減少鎖的影響:

  • 刪除小批量在低負荷小時數
  • 運行刪除工作考慮不刪除所有,如果它不會節省您太多的空間
  • 而不是刪除行將它們標記爲「已刪除」或已過時並從SELECT中排除q ueries

更小的物體鎖定(而不是鎖定在一次所有表):

  • 有幾個DELETE語句從各基礎表的刪除
  • 降MERGE定義,刪除數據從每個基礎表創建MERGE。不過,我認爲你可以在不降低MERGE定義的情況下做到這一點。
  • 使用分區。從MySQL手冊

引用:

到一個MERGE表的替代方案是一個分區表,其存儲在單獨的文件中的單個表的 分區。分區使得 某些操作可以更有效地執行,並且不限於 MyISAM存儲引擎。有關更多信息,請參閱Chapter 18, Partitioning

我強烈主張分割,這是因爲: - 您可以完全自動化你的日誌/數據保存過程:一個腳本可以創建新的和刪除的空分區中,過時的數據移動到不同的表,然後截斷表。 - 強制實施密鑰唯一性 - 只鎖定包含要刪除數據的分區。在其他分區上選擇正常運行。 - 搜索同時在所有分區上運行(與MERGE一樣),但您可以使用HASH SubPartitioning來進一步加快搜索速度。

但是,如果您認爲分區的好處將超過開發成本,那麼您可能根本不應刪除該數據?

1

我認爲最好的解決方案將根據用戶設置的日誌partitions合併的MyISAM ID。這種方式當你運行一個刪除時,db將只阻塞一個分區。

+0

感謝名單...........分區是非常明顯的,但我有記錄億盧比,我也使用合併表(表1merge =1個月= 2crore)。在第4個月,我改變了認定中... ...........同時使用合併和分區是最後一次soln我在想 – chicharito

+0

但是你用什麼合併? – Moby04

+0

更新問題 – chicharito

1

如果你在谷歌上的「刪除巨大的桌子上」,你會得到一些信息的結果。這裏是前三分命中:

http://www.dba-oracle.com/t_oracle_fastest_delete_from_large_table.htm

Improving DELETE and INSERT times on a large table that has an index structure

http://www.dbforums.com/microsoft-sql-server/1635228-fastest-way-delete-large-table.html

一種方法都提到的是小批量的,而不是一次全部刪除。你說這個表格包含了2個月的數據。也許你分別爲每一天運行刪除語句?

我希望這有助於!

+0

每當我執行刪除操作時,都會發生巨大的鎖定。 我正在尋求避免 – chicharito

0

如果使用InnoDB和創建外鍵關係,就可以得到行自動當用戶自己刪除刪除:

CREATE TABLE `DailyChoices`(

sender INT(11)NOT NULL, receiver INT(11)NOT NULL, CONSTRAINT FOREIGN KEY(sender)參考文獻usersuserid)ON DELETE CASCADE ON UPDATE CASCADE )TYPE = InnoDB;