2012-05-30 22 views
0

我想設計一個快速數據庫模式,該模式可以像更新條目一樣處理排序和篩選列。針對高度經常更改的條目的最佳數據庫模式

爲此,我創建了以下場景:

  • 事件都有一個確切的名稱,狀態,上次訂購的日期,描述和一個位置
  • 的一個事件可用座位數保存隨着事件,每次將被更新的參與者subcribes
  • 每一個事件都只有一個類別
  • 只能按類別
  • 事件被列出的事件可以按名稱,狀態或日期(不XOR)
  • 事件可以按名稱,狀態或日期(XOR)進行排序
  • 表必須處理超過10 MIO項

對於被過濾所有測試我使用MySQL和InnoDB表。我也嘗試儘可能多地使用多個插入/更新/刪除。一個用於類,另一個用於事件: 過濾是通過使用LIKE「%[字]%」

首先我試圖使用2個表來完成。索引是分類名稱,分類狀態名稱,分類日期名稱和分類日期狀態名稱。 爲此,列表,過濾和排序非常快,但插入,更新或刪除條目非常緩慢。我也有鎖超時,因爲重建索引花費了太多時間。

第二次嘗試是有3個表:類別,事件和位置。 但是,如果位置表包含6 mio或更多的條目,它也變得很慢。我認爲是因爲快速捕撈的指標。添加100k條目需要約272秒。的位置各指標主要指數ID拉鍊街

下一個嘗試是創建一個自己的表,最後預訂的日期和計數器。但是如何過濾這個日期或者對這個日期進行分類呢?

是更好地有3個指標,如:類別的名稱,類別,日期,類別狀態或者是我用4個指標類別的名稱,類別,狀態,名稱,類別,日期,名稱的解決方案和類別日期 - 狀態名稱對MySQL更好?

我也在考慮字段類型:目前我使用VARCHAR作爲名稱。但是CHAR可能更好,因爲每個條目的長度都相同,所以跳到索引中的特定位置比使用變量長度更快。你怎麼看?

有人有一些提示如何設計一個好的和快速的數據庫架構,支持如上所述的場景?

+1

索引是固定長度的,所以CHAR vs VARCHAR對索引無關緊要,儘管它對於表掃描很重要。 –

+0

我不知道這一點。謝謝。我試圖通過在所有相關列上添加索引來避免表掃描 –

回答

1

索引是固定長度的,所以CHAR vs VARCHAR對索引無關緊要,儘管它對於表掃描很重要。

我不認爲我可以提供任何其他明確的答案,沒有具體細節。我可以給你一些一般的建議。

您應該避免插入聚簇索引(InnoDB主鍵或第一個唯一鍵)。聚簇索引通常與自動遞增的列一起使用,以便索引僅附加到中,而沒有任何內容插入到中間。這避免了必須重建索引。

對於非集羣(二級)索引,索引越大,插入時必須重建的次數越多。可以執行插入,直到頁面填滿,然後重新構建。再次,追加到索引的末尾是好的。

刪除不影響性能,因爲索引只標記爲刪除,索引在空閒時間內重建。

索引不應該在低基數的列上創建,因爲MySQL不會使用它們。只應根據需要添加索引,每次衡量優勢和劣勢。

多列索引較大(較少的條目適合頁面)並需要更新更多的條目。謹慎添加多列索引。

MyISAM更適合頻繁讀取,但由於鎖爭用(表鎖)而導致在多用戶環境中經常更新/插入,導致頻繁更新/插入。由於較少的鎖爭用(行鎖),InnoDB更適合多用戶環境中的更新,但讀取速度較慢(仍需要行鎖)。

篩選形式LIKE '%[word]%'不能使用索引,儘管篩選LIKE '[word]%'可以使用索引。

在經常更新的系統上,索引對於選擇要更新的記錄和讀取它們時同等重要。索引越好,爭用鎖越少,因此性能越好,死鎖越少。

JOIN越多,成本越高,查詢越慢。 JOINs不錯,但JOINs在多行(一個大的結果集)可能會很慢。

一些非性能相關的注意事項:

有了InnoDB的,你應該準備好如何處理因死鎖失敗的交易。

+0

如何使用主鍵無效插入到具有主鍵的表的聚集索引中? –

+0

只有InnoDB具有聚簇索引。正常的解決方案,如果你不得不經常插入一個自然的主鍵,就是使用代理auto_increment主鍵,所以你總是追加到聚集索引的末尾而不是插入。 –

相關問題