2015-06-28 23 views
0

背景信息:我們運行一個電子商務網站,並試圖找出處理非常頻繁使用的表的「歷史」數據的最佳方法,必須包含大量記錄(即訂單,客戶等)。在表格增長後優化MySQL操作的最佳方式

我特別期待在2個特定的場景:

  • DB遷移
  • 的SELECT

DB遷移

在DB遷移的情況下,我們開始看到,我們有時需要運行一些鎖定整個表的ALTER TABLE,如果表有這麼多的記錄,這可能需要一段時間。當然,桌面上的所有操作都處於暫停狀態,直到遷移完成,這意味着我們的結帳可能會因爲我們將VARCHAR(15)更改爲VARCHAR(256)而關閉。

從MySQL 5.6,很多操作完成「INPLACE」,這意味着(從what I understood),他們不會被創建全表鎖:這是確定十歲上下,但仍不夠完善 - 如果我們需要改變什麼列的類型(不能執行INPLACE),我們真的不想在幾分鐘內進入維護模式?

我的超貧民窟的想法是簡單地複製表(複製它),然後在複製的表上執行遷移,停止寫入原始表(即鎖定它),將未同步的數據複製到複製一個並交換它們。我認爲percona tool for zero-downtime migrations做了類似的事情,所以也許這是「最好的」方法?

意見?

的SELECT

SELECTs,因爲大多數的舊數據的訪問很少,我想到了range-partitioning它按日期(比如預2015年/ 2015年後爲例),然後改變我們的大部分查詢到取東西WHERE YEAR(created_at) >= 2015

如果用戶想要他的完整歷史數據,那麼我們會動態地刪除該條件。這不知何故確保數據是well-partitioned

還有其他想法嗎?你認爲分區可能是值得的嗎?

回答

0
  • 直到5.7.1你能很快做到這一點:

VARCHAR大小可以使用就地ALTER TABLE這個例子可以增加,因爲在 :

ALTER TABLE t1 ALGORITHM = INPLACE,CHANGE COLUMN c1 c1 VARCHAR(255);

  • pt-online-schema-change

  • 如果你已經有複製設置,那麼你可以玩奴隸的遊戲ALTERing,然後失敗。(是的,Percona工具在這方面很方便。)

  • 不要'隱藏'欄內功能;優化器無法看到它們:

    WHERE YEAR(created_at)> = 2015 - > WHERE created_at> = '2015年1月1日'

  • 劃分成只有2個分區是不太可能提供任何性能優勢。

  • 合理(通常和完成)一些日期(例如,TO_DAYS())爲最終淨化(通過DROP PARTITION)舊數據的目的PARTITION BY RANGEDROP比單純的DELETE要快得多,而且侵入性也小,因此單獨證明了分區是合理的。你提到的修剪很少加速查詢(除非索引很差)。 More discussion of sliding time series

+0

Got it!謝謝! – odino