一些加速 MyISAM
資料表查詢的通用提示
為了幫助 MySQL 更好地優化查詢,請在使用資料載入資料表後,使用
ANALYZE TABLE
或在資料表上執行 myisamchk --analyze。這會為每個索引部分更新一個值,該值指示具有相同值的平均列數。(對於唯一索引,此值始終為 1。) 當您基於非常數表達式聯結兩個資料表時,MySQL 會使用此值來決定要選擇哪個索引。您可以使用SHOW INDEX FROM
並檢查tbl_name
Cardinality
值來檢查資料表分析的結果。 myisamchk --description --verbose 顯示索引分佈資訊。要根據索引排序索引和資料,請使用 myisamchk --sort-index --sort-records=1 (假設您想要依索引 1 排序)。如果您有一個唯一的索引,您想要從該索引依索引順序讀取所有列,這是一種加速查詢的好方法。第一次以這種方式排序大型資料表時,可能需要很長時間。
請盡量避免在經常更新的
MyISAM
資料表上執行複雜的SELECT
查詢,以避免因讀取器和寫入器之間的爭用而導致的資料表鎖定問題。MyISAM
支援並行插入:如果資料表在資料檔案中間沒有可用區塊,您可以同時將新列INSERT
到其中,同時其他執行緒正從資料表讀取資料。如果能夠執行此操作很重要,請考慮以避免刪除列的方式使用資料表。另一種可能性是在您從資料表刪除大量列之後,執行OPTIMIZE TABLE
來對資料表進行碎片整理。此行為會因設定concurrent_insert
變數而改變。您可以強制將新列附加 (因此允許並行插入),即使在刪除列的資料表中也是如此。請參閱 第 10.11.3 節,「並行插入」。對於經常變更的
MyISAM
資料表,請盡量避免所有可變長度欄位 (VARCHAR
、BLOB
和TEXT
)。如果資料表包含哪怕單一可變長度欄位,則該資料表會使用動態列格式。請參閱 第 18 章,其他儲存引擎。通常將資料表分割成不同的資料表並不是很有用,僅僅是因為列變得很大。在存取列時,最大的效能瓶頸是尋找列的第一個位元組所需的磁碟搜尋。在找到資料後,大多數現代磁碟可以快速讀取整列,足以滿足大多數應用程式的需求。分割資料表產生顯著差異的唯一情況是,如果它是使用您可以變更為固定列大小的動態列格式的
MyISAM
資料表,或者如果您經常需要掃描資料表,但不需要大多數欄位。請參閱 第 18 章,其他儲存引擎。如果您通常以
順序擷取列,請使用expr1
,expr2
, ...ALTER TABLE ... ORDER BY
。在資料表進行大量變更後使用此選項,您或許可以獲得更高的效能。expr1
,expr2
, ...如果您經常需要根據大量資料列的資訊來計算結果(例如計數),最好引入一個新表格並即時更新計數器。以下形式的更新速度非常快:
UPDATE tbl_name SET count_col=count_col+1 WHERE key_col=constant;
當您使用僅具有表格級鎖定的 MySQL 儲存引擎(例如
MyISAM
)(多個讀取器和單個寫入器)時,這一點非常重要。在大多數資料庫系統中,這也能提供更好的效能,因為在這種情況下,資料列鎖定管理器的負擔較小。定期使用
OPTIMIZE TABLE
來避免動態格式的MyISAM
表格出現碎片。請參閱第 18.2.3 節,「MyISAM 表格儲存格式」。使用
DELAY_KEY_WRITE=1
表格選項宣告MyISAM
表格,可以加快索引更新速度,因為它們在表格關閉之前不會刷新到磁碟。缺點是,如果伺服器在開啟此類表格時崩潰,您必須透過設定myisam_recover_options
系統變數來執行伺服器,或是在重新啟動伺服器之前執行 myisamchk,來確保表格正常。(不過,即使在這種情況下,您也不會因為使用DELAY_KEY_WRITE
而遺失任何資料,因為索引鍵資訊始終可以從資料列產生。)字串在
MyISAM
索引中會自動進行前綴和尾部空格壓縮。請參閱第 15.1.15 節,「CREATE INDEX 陳述式」。您可以透過在應用程式中快取查詢或答案,然後一起執行多個插入或更新操作來提高效能。在此操作期間鎖定表格可確保索引快取在所有更新完成後只刷新一次。