高性能MySql進化論(二):數據類型的優化_下

·????????blob/text
在實際的應用程序中往往需要存儲兩種體積較大的數據,一種是較大的binary數據,e.g. 一張10m的圖片,另外一種是 較大的文本 e.g.一篇幾萬字的文章。在oracle中有bolb和clob來應對這兩種數據,而在mysql中對應的是blob以及text.
鑒于這兩種數據類型的特殊性,在mysql中對blob以及text的存儲和操作做了特殊的處理:
????????? 1) blob/text 的值往往是作為對象來處理,這些對象有自己的id,以及獨立的存儲空間
????????? 2) blob/text的值被用來排序的時候,只有前n個字節會被使用,n 對應的是數據庫中的一個常量值 (max_sort_length), 如果你想指定更多的字節被用來排序,那么你可以增加max_sort_length的值或者是使用order by substring(column, length)函數來處理
????????? 3) 當blob/text 被用作索引或者排序的時候,不能使用整個字段的值.
在萬不得已的情況下要避免把bolb/text用作索引或是排序

因為mysql 的memory 引擎不支持blob 和text 類型,所以,如果查詢的過程中涉及到blob /text,則需要使用myisam 磁盤臨時表,即使只有幾行數據也是如此(在最新的percona server 的memory 引擎支持blob 和text 類型)。

Memory引擎頻繁的訪問磁盤臨時表會產生嚴重的性能開銷,最好的解決方案是盡量避免使用BLOB 和TEXT 類型。如果實在無法避免,有一個技巧是在所有用到BLOB 字段的地方都使用SUBSTRING(column, length) 將列值轉換為字符串(在ORDER BY 子句中也適用),這樣就可以使用內存臨時表了。但是要確保截取的子字符串足夠短,不會使臨時表的大小超過max_heap_table_size 或tmp_table_size,超過以后MySQL 會將內存臨時表轉換為MyISAM 磁盤臨時表。

?

最壞情況下的長度分配對于排序的時候也是一樣的,所以這一招對于內存中創建大臨時表和文件排序,以及在磁盤上創建大臨時表和文件排序這兩種情況都很有幫助。例如,假設有一個1 000 萬行的表,占用幾個GB 的磁盤空間。其中有一個utf8字符集的VARCHAR(1000) 列。每個字符最多使用3 個字節,最壞情況下需要3 000字節的空間。如果在ORDER BY 中用到這個列,并且查詢掃描整個表,為了排序就需要超過30GB 的臨時表

·?????? DATETIME/TIMESTAMP
在MySQL中包含兩種時間格式 DATETIME,TIMESTAMP, 通常在使用的過程中這兩種類型區別不是很大,但是在細節上還是存在差別

高性能MySql進化論(二):數據類型的優化_下

因為TMESSTAMP會占用更小的存儲空間,所以可以使用它作為默認的時間格式

·?????? ENUM
這種類型的字段主要是通過枚舉的方式來保存列的值,因為在使用的過程中會涉及到枚舉位置與實際值的轉換,所以對于整體的性能可能會有一定的影響,而且枚舉的值是存儲在.frm(數據表結構定義文件)中,所以當建立完ENUM的列后,如果你想對EMUM的內容進行更新,也就相當于做了表結構的更新。
下面是個簡單建立ENUM列的例子:

mysql>?CREATE?TABLEenum_test(  ->??e?ENUM('fish',?'apple',?'dog')?NOT?NULL  ->?);  mysql>?INSERT?INTOenum_test(e)?VALUES('fish'),?('dog'),?('apple');

·????????BIT
如果需要讓你設計一個表示布爾值的字段要求占用的空間最少,你會如何去設計?用INT,還是用CHAR(1)?相比INT以及CHAR(1)而言BIT(1)或許是個更好的選擇,因為它占用的空間只是一個BIT。它可以通過BIT(N)的方式來表達多個BIT的值,這種方式最大支持到BIT(64)。

在MySQL5.0之前的版本中,BIT被認為是和TINYINT等同的,在新的版本中被作為兩種完全不同的類型來對待。

當你把一個BIT字段從數據庫中檢索出來顯示在控制臺上時,值會被顯示成ASCII編碼,當字段的值出在一個數字運算的上下文時,它會被當成是BIT的十進制的值,下面的一個例子可以很清楚的說明這兩種情況

mysql>CREATE?TABLE?bittest(a?bit(8));  mysql>?INSERT?INTObittest?VALUES(b'00111001');  mysql>?SELECT?a,?a+?0?FROM?bittest;  +------+-------+  |?a?|?a?+?0?|  +------+-------+  |?9?|?57?|  +------+-------+

上面的這個例子或許會讓你感到困惑,很有可能讓你不再想使用這種機制來存儲單個的位,作為一種替代方案可以把相關字段設置成CHAR(0),NULL用來表示False,””(Empty String)表示True

以上就是?高性能MySql進化論(二):數據類型的優化_下的內容,更多相關內容請關注PHP中文網(www.php.cn)!

? 版權聲明
THE END
喜歡就支持一下吧
點贊12 分享