4.4 有效地裝載數據
很多時候關心的是優化SELECT 查詢,因為它們是最常用的查詢,而且確定怎樣優化它們並不總是直截了當。相對來說,將數據裝入數據庫是直截了當的。然而,也存在可用來改善數據裝載操作效率的策略,其基本原理如下:
■ 成批裝載較單行裝載更快,因為在裝載每個記錄後,不需要刷新索引高速緩存;可在成批記錄裝入後才刷新。
■ 在表無索引時裝載比索引後裝載更快。如果有索引,不僅必須增加記錄到數據文件,而且還要修改每個索引以反映增加了的新記錄。
■ 較短的SQL 語句比較長的SQL 語句要快,因為它們涉及服務器方的分析較少,而且還因為將它們通過網絡從客戶機發送到服務器更快。這些因素中有一些似乎微不足道(特別是最後一個因素),但如果要裝載大量的數據,即使是很小的因素也會產生很大的不同結果。我們可以利用上述的一般原理推導出幾個關於如何最快地裝載數據的實際結論:
■ LOAD DATA(包括其所有形式)比I N S E RT 效率高,因為其成批裝載行。索引刷新較少,並且服務器只需分析和解釋一條語句而不是幾條語句。
■ LOAD DATA 比LOAD DATA LOCAL 效率更高。利用LOAD DATA,文件必須定位在服務器上,而且必須具有FILE 權限,但服務器可從磁盤直接讀取文件。利用LOAD DATA LOCAL,客戶機讀取文件並將其通過網絡發送給服務器,這樣做很慢。
■ 如果必須使用I N S E RT,應該利用允許在單個語句中指定多行的形式,例如:
可在語句中指定的行越多越好。這樣會減少所需的語句數目,降低索引刷新量。如果使用mysqldump 生成數據庫備份文件,應該使用--extended-insert 選項,使轉儲文件包含多行I N S E RT 語句。還可以使用- - o p t(優化) ,它啟用--extended-insert 選項。
反之,應該避免使用mysqldump 的--complete-insert 選項;此選項會導致I N S E RT 語句為單行,執行時間更長,比不用--complete-insert 選項生成的語句需要更多的分析。
■ 使用壓縮了的客戶機/服務器協議以減少網絡數據流量。對於大多數MySQL 客戶機,可以用--compress 命令行選項來指定。它一般只用於較慢的網絡,因為壓縮需要占用大量的處理器時間。
■ 讓MySQL 插入缺省值;不要在I N S E RT 語句中指定將以任意方式賦予缺省值的列。平均來說,這樣做語句會更短,能減少通過網絡傳送給服務器的字符數。此外,語句包含的值較少,服務器所進行的分析和轉換就會較少。
■ 如果表是索引的,則可利用批量插入( LOAD DATA 或多行的I N S E RT 語句)來減少索引的開銷。這樣會最小化索引更新的影響,因為索引只需要在所有行處理過時才進行刷新,而不是在每行處理後就刷新。
■ 如果需要將大量數據裝入一個新表,應該創建該表且在未索引時裝載,裝載數據後才創建索引,這樣做較快。一次創建索引(而不是每行修改一次索引)較快。
■ 如果在裝載之前刪除或禁用索引,裝入數據後再重新創建或啟用索引可能使裝載更快。如果想對數據裝載使用刪除或禁用策略,一定要做一些實驗,看這樣做是否值得(如果將少量數據裝入一個大表中,重建和索引所花費的時間可能比裝載數據的時間還要長)。
可用DROP INDEX 和C R E ATE INDEX 來刪除和重建索引。另一種可供選擇的方法是利用myisamchk 或isamchk 禁用和啟用索引。這需要在MySQL 服務器主機上有一個帳戶,並對表文件有寫入權。為了禁用表索引,可進入相應的數據庫目錄,執行下列命令之一: