這一部分提供了如何選擇數據類型來幫助提高查詢運行速度的一些指導:
在可以使用短數據列的時候就不要用長的。如果你有一個固定 長度的CHAR數據列,那么就不要讓它的長度超出實際需要。如果你在數據列中存儲的最長的值有40個字符,就不要定義成CHAR(255),而應該定義成 CHAR(40)。如果你能夠用MEDIUMINT代替BIGINT,那么你的數據表就小一些 (磁盤I/O少一些),在計算過程中,值的處理速度也快一些。如果數據列被索引了,那么使用較短的值帶來的性能提高更加顯著。不僅索引可以提高查詢速度, 而且短的索引值也比長的索引值處理起來要快一些。
如果你可以選擇數據行的存儲格式,那么應該使用最適合存儲引擎的那種。對於 MyISAM數據表,最好使用固定長度的數據列代替可變長度的數據列。例如,讓所有的字符列用CHAR類型代替VARCHAR類型。權衡得失,我們會發現 數據表使用了更多的磁盤空間,但是如果你能夠提供額外的空間,那么固定長度的數據行被處理的速度比可變長度的數據行要快一些。對於那些被頻繁修改的表來 說,這一點尤其突出,因為在那些情況下,性能更容易受到磁盤碎片的影響。
在使用可變長度的數據行的時候,由於記錄長度不同,在多次執行刪除和更新操作之后,數據表的碎片要多一些。你必須使用OPTIMIZE TABLE來定期維護其性能。固定長度的數據行沒有這個問題。
如果出現數據表崩潰的情況,那么數據行長度固定的表更容易重新構造。使用固定長度數據行的時候,每個記錄的開始位置都可以被檢測到,因為這些位置都是固 定記錄長度的倍數,但是使用可變長度數據行的時候就不一定了。這不是與查詢處理的性能相關的問題,但是它一定能夠加快數據表的修復速度。
盡管把MyISAM數據表轉換成使用固定長度的數據列可以提高性能,但是你首先需要考慮下面一些問題:
固定長度的數據列速度較快,但是占用的空間也較大。CHAR(n)列的每個值(即使是空值)通常占n個字符,這是因為把它存儲到數據表中的時候,會在值的后面添加空格。VARCHAR(n)列占有的空間較小,因為只需要分配必要的字符個數用於存儲值,加上一兩個字節來存儲值的長度。因此,在CHAR和VARCHAR列之間進行選擇的時候,實際上是時間與空間的對比。如果速度是主要的考慮因素,那么就使用CHAR數據列獲取固定長度列的性能優勢。如果空間很重要,那么就使用VARCHAR數據列。總而言之,你可以認為固定長度的數據行可以提高性能,雖然它占用了更大的空間。但是對於某些特殊的應用程序, 你可能希望使用兩種方式來實現某個數據表,然后運行測試來決定哪種情況符合應用程序的需求。
即使願意使用固定長度類型,有時候你也沒有辦法使用。例如,長於255個字符的字符串就無法使用固定長度類型。
MEMORY數據表目前都使用固定長度的數據行存儲,因此無論使用CHAR或VARCHAR列都沒有關系。兩者都是作為CHAR類型處理的。
對於InnoDB數據表,內部的行存儲格式沒有區分固定長度和可變長度列(所有數據行都使用指向數據列值的頭指針),因此在本質上,使用固定長度的 CHAR列不一定比使用可變長度VARCHAR列簡單。因而,主要的性能因素是數據行使用的存儲總量。由於CHAR平均占用的空間多於VARCHAR,因 此使用VARCHAR來最小化需要處理的數據行的存儲總量和磁盤I/O是比較好的。
對於BDB數據表,無論使用固定長度或可變長度的數據列,差別都不大。兩種方法你都可用試一下,運行一些實驗測試來檢測是否存在明顯的差別。
把數據列定義成不能為空(NOT NULL)。這會使處理速度更快,需要的存儲更少。它有時候還簡化了查詢,因為在某些情況下你不需要檢查值的NULL屬性。
考慮使用ENUM數據列。如果你擁有的某個數據列的基數很低(包含的不同的值數量有限),那么可以考慮把它轉換為ENUM列。ENUM值可以被更快地處理,因為它們在內部表現為數值。
使用PROCEDURE ANALYSE()。運行PROCEDURE ANALYSE()可以看到數據表中列的情況:
SELECT * FROM tbl_name PROCEDURE ANALYSE(); SELECT * FROM tbl_name PROCEDURE ANALYSE(16,256);
輸出的每一列信息都會對數據表中的列的數據類型提出優化建議。第二個例子告訴PROCEDURE ANALYSE()不要為那些包含的值多於16個或者256字節的ENUM類型提出建議。如果沒有這樣的限制,輸出信息可能很長;ENUM定義通常很難閱讀。
轉載:http://dev.yesky.com/103/2114603.shtml?412
