在記憶體中記憶體 MySQL 數據庫
我在使用 600MB MySQL 數據庫的網站時遇到問題。網站太慢了。我注意到 MySQL 數據庫越大,執行速度就越慢。當它是 5MB 時,網站非常快。當它開始變大時,它開始變得越來越慢,現在,在 600MB 時,它真的很慢,載入頁面大約需要 10 秒。
我檢查了頂級程序,它與高負載或任何東西無關。它甚至與 IOPS 無關,因為我在 HDD 7.2k rpm 驅動器上進行了測試,並且現在在使用 Intel 320 SSD 驅動器進行測試時也出現了同樣的問題,所以我認為這也與高查詢無關。
該網站正在使用 Wordpress,並且有 9 個外掛處於活動狀態。人們說它可能是外掛……好吧也許……但現在我只想將整個數據庫記憶體在記憶體中,並希望獲得有關從哪裡開始以及如何做的幫助和指導。
我有 16GB RAM 和 i5-2400 4 核 @ 3.1 GHz。作業系統是centos 5.7
top - 07:23:57 up 9 days, 12:15, 0 users, load average: 0.09, 0.04, 0.05 Tasks: 162 total, 1 running, 161 sleeping, 0 stopped, 0 zombie Cpu(s): 8.2%us, 1.0%sy, 0.0%ni, 90.7%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st Mem: 16367532k total, 3641628k used, 12725904k free, 612140k buffers Swap: 1046520k total, 0k used, 1046520k free, 1538896k cached
如果我是你,我會將所有數據切換到 InnoDB。長期以來,許多人都在討論表鎖定/行鎖定。我總是會毫不猶豫地選擇 InnoDB。然而,選擇 InnoDB…CACHING 還有另一個深刻的原因。
雖然大多數人吹噓 MyISAM 的讀取速度更快,但大多數人忘記了 MyISAM 的許多記憶體,稱為鍵記憶體(由 key_buffer_size 設置),僅記憶體來自 .MYI 文件的索引頁。它從不記憶體數據頁。它在 32 位系統中的官方最大容量為 4GB。8GB 是 64 位的最佳最大值。
InnoDB 緩衝池記憶體數據和索引頁面。根據您擁有的伺服器,您可以將整個數據集記憶體到 RAM 中。您可以將 InnoDB 調整為高達 80% 的 RAM 和 10% 的 DB Conenctions,並為作業系統留出 10%。即使對於不同的作業系統也是如此。
我已經向 Drupal 客戶推薦了這些東西,並取得了巨大的成功。它也適用於 Wordpress。我已經為使用 WordPress 的客戶提供了數據庫支持。同樣的改進。
你總是可以更有效地為 InnoDB 配置記憶體,而不是更多的 MyISAM。總有一種方法可以調整 InnoDB 以滿足您的性能需求。隨著數據的增長,它最終將成為一項需求。
更新 2011-11-21 11:44 EST
如果您的完整數據集足夠小,您可以在 mysql 啟動後立即對您擁有的每個表執行 SELECT 查詢。
對於所有 InnoDB 和/或 MyISAM 表,執行以下查詢:
SELECT DISTINCT CONCAT('SELECT ',ndxcollist,' FROM ', db,'.',tb,' ORDER BY ',ndxcollist,';') SelectQueryToLoadCache FROM ( SELECT engine,table_schema db,table_name tb,index_name, GROUP_CONCAT(column_name ORDER BY seq_in_index) ndxcollist FROM ( SELECT B.engine,A.table_schema,A.table_name, A.index_name,A.column_name,A.seq_in_index FROM information_schema.statistics A INNER JOIN (SELECT engine,table_schema,table_name FROM information_schema.tables WHERE engine IN ('InnoDB','MyISAM')) B USING (table_schema,table_name) WHERE B.table_schema NOT IN ('information_schema','mysql') AND A.index_type <> 'FULLTEXT' ORDER BY table_schema,table_name,index_name,seq_in_index ) A GROUP BY table_schema,table_name,index_name ) AA ORDER BY engine DESC,db,tb ;
這將輸出您需要執行的所有可能的 SELECT 查詢,該查詢將呼叫所有要引用的索引。將此查詢放在名為 /root/MakeSelectQueriesToLoad.sql 的文件中。執行腳本並收集輸出 /root/SelectQueriesToLoad.sql。最後,執行它:
mysql -u... -p... -AN < /root/MakeSelectQueriesToLoad.sql > /root/SelectQueriesToLoad.sql mysql -u... -p... < /root/SelectQueriesToLoad.sql
這肯定會將所有索引頁面預載入到 InnoDB 緩衝池和 MyISAM 密鑰記憶體中。如果您的所有數據都是 InnoDB,請進行兩項更改:
- 替換
WHERE engine IN ('InnoDB','MyISAM')
為WHERE engine='InnoDB'
- 替換
CONCAT('SELECT ',ndxcollist,' FROM ',
為CONCAT('SELECT * FROM ',
這也會將更多數據頁填充到 InnoDB 緩衝池中。
您已經將整個數據庫記憶體在記憶體中。問題幾乎可以肯定是搜尋數據庫所需的時間,即使在 RAM 中也是如此。
查看您的磁碟 I/O 統計資訊。您可能會看到磁碟 I/O 只是偶爾出現隨機位。數據庫在記憶體中。那不是問題。您需要先安裝
iostat
。您沒有提及您的平台或發行版,但它可能位於名為iostat
. 你可能會發現atop
更友好。在得到任何證據表明您的整個數據庫尚未在記憶體中或磁碟 I/O 是問題之後,告訴您的人是否這樣做了?否則,他們的建議就相當於一位醫生從未看過或檢查過您,但只是聽說您的手臂受傷告訴您要在上面打石膏。