具有許多索引的 InnoDB 與 MyISAM
我不確定這個問題是否有正確或錯誤的答案,因為我認為這嚴重取決於情況,但為了心理鍛煉,我還是會繼續問:
我的數據庫中有一個 MyISAM 表,它位於我的站點的中心。圍繞它創建了許多參考表,並且許多其他表直接連結到該表中的行 ID。該表大約有 260k 行,有 28 個欄位,其中大部分是 varchars 和 int。我有大約 15 個索引(數據大約 70 MiB,索引大約 80 MiB)。每天可能有數百次寫入,而讀取數以萬計。我的數據庫位於 SSD 驅動器上。
現在我的問題是;將此表更改為 InnoDB 表是否有益?我正在努力擴展我的系統以包括 API 流量,這意味著該表甚至會被查詢更多,我想確保一切執行盡可能順利。因此,我稍微傾向於將其轉換為 InnoDB。但是,由於該表需要許多索引,我認為 MyISAM 可能會更有效地工作。誰能幫我下定決心?提前謝謝1
編輯:(由 jcolebrand 從評論中添加)
很久以前我已經添加了索引,並且我對 PHP 程式碼庫進行了一些更改,所以可能有些索引已經過時,但總體而言;是的,它們都被使用了。我在表上執行了許多不同類型的查詢。不同的查詢,不同的索引。但是我這裡的主要問題不涉及表讀取性能,而是它如何處理許多索引。InnoDB 索引與數據一起“離開”/儲存,而不是 MyISAM 的密鑰文件原則。我只是擔心這可能會導致足夠的性能下降而不會超過表鎖定問題。
每天可能有數百次寫入,而讀取數以萬計。我的數據庫位於 SSD 驅動器上。
基於這個陳述,讓我們玩一些數字。假設每天有 500 次寫入和 20,000 次讀取。計算結果如下
- 每天 97.56% 的閱讀量
- 每天寫入 2.44%
- 40 次讀取/寫入
儘管我很喜歡 InnoDB,但在這種情況下我不得不選擇 MyISAM 有幾個原因
原因 #1
您只有 150MiB 的 MyISAM 表(70MiB 數據,80 MiB 索引)
原因 #2
InnoDB 索引往往會變得非常臃腫,因為二級索引具有進入聚集索引的鍵。這總是導致雙索引查找。大型、寫入量大的數據集可能會忽略這一點。
原因 #3
InnoDB 表空間往往會變得非常臃腫,因為 MVCC 在沒有自動回收磁碟空間的情況下被創建和丟棄:
禁用innodb_file_per_table後,系統表空間文件ibdata1將穩步增長,回收磁碟空間的機會為 0%。您必須將 InnoDB 儲存引擎轉換為使用 innodb_file_per_table。
啟用innodb_file_per_table後,您可以轉到單個 InnoDB 並執行以下命令以物理收縮 InnoDB表
mydb.mytable
:
OPTIMIZE TABLE mydb.mytable;
ALTER TABLE mydb.mytable ENGINE=InnoDB;
MyISAM 可以避免這一切
原因 #4
InnoDB 通過為事務控制執行 MVCC 來保護各個行。一天內產生的讀取成本可能會超過 150 MiB。
我可能還有 2 或 3 個原因,但讓我們切入正題:在您的情況下,有什麼可以提高 MyISAM 的性能的嗎?為什麼,是的。
你說了以下
該表大小約為 260k 行,有 28 個欄位,其中大部分是 varchars 和 ints
如果您有許多 varchar,您可以採取一些措施來提高讀/寫性能。對於任何 MyISAM 表
mydb.mytable
:執行以下命令:ALTER TABLE mydb.mytable ROW_FORMAT=Fixed;
這會做什麼,這會將所有 VARCHAR 視為 CHAR。每行將是完全相同的長度。這將使磁碟空間增加 80%-100%。在您的情況下,假設它將您的 150 MiB MyISAM 表翻倍至 300 MiB。好處在哪裡?您的 MyISAM 表現在可以在任何地方以 20% - 30% 的速度讀取/寫入,而無需更改我從MySQL Database Design and Tuning第 72,73 頁學到的任何其他內容。
我在過去寫過這個:
- InnoDB 和 MyISAM 哪個更快?(2012 年 5 月 3 日)
- 選擇哪個mysql儲存引擎?(2012 年 5 月 2 日)
- MyISAM 和 InnoDB 最佳(2011 年 9 月 20 日)
- 哪個 DBMS 適合超快速讀取和簡單的資料結構?(2011 年 8 月 12 日)
- 在固定大小的欄位上使用 CHAR 與 VARCHAR 對性能有何影響?(2011 年 5 月 10 日)