【高性能mysql】-字段類型的選擇

1. 優化數據類型

    1.0 幾個簡單的原則

             1.更小的通常更好:儘量選擇可以正確存儲數據的最小數據類型。如int-->tinyint, 

             2.簡單就好:使用更少耗費cpu的類型。如整形比字符串操作代價更低;使用mysql內建的時間/日期類型而不是字符串存儲時間;使用整數存儲ip地址等等

           3.  儘量避免 null 。如果查詢帶有null的列,對mysql來說更難優化。null使索引、索引統計、值比較都更加複雜。

  

1.1 整數類型

      1儘量確定整數的範圍並使用對應的整形,tinyint/int/smallint/bigint等。

      2 合理利用unsigned  :如果只有正整數,不妨在之後加上unsigned 修飾

     3.  雖然int可以指定長度。如int(11),但這只是規定了顯示的字符個數,實際上存儲和計算的仍是int類型的數值。比如int(1)和int(20)只是顯示的值不同。

1.2 實數類型

  1 使用decimal 可以用來存儲比bigint還大的數據。

 2  使用bigint 來避免浮點型計算不精確以及decimal 精確計算代價高的問題。例如,存儲財務數據,單位爲萬元時,存在小數的情況。可以直接使用單位爲元或者/角/分的更小單位的bigint數值來替代。

1.3  字符串類型

先講char和varchar 

varchar 用來存儲不定長的字符串,它比定長類型更省空間(除非使用row_format=fixed創建,每一行都會使用定長字符串)。

varchar需要使用額外1或2字節存儲字符長度。如果長度<=255,則使用1字節,否則使用2字節。

varchar由於更新變長時,myisam和innodb的處理方式不同。myisam會將行拆分成不同的片段存儲,innodb則進行分裂頁來使行可以放入頁內。innodb還會將過長的varchar轉換爲blob

   適合varchar 的場景:

                字符串列最大長度比平均長度大很多;

               字符串列更新少;

               使用了utf-8等複雜的字符集。

blob和text 

blob 存儲二進制,text存儲文本。

對blob和text進行排序時,只會對每列的前max_sort_length 字節進行排序。如果非要對其進行排序可以更改此變量值,或者使用 ` order by  sustring(coulmn,length)`。

 

1.4 日期和時間類型

    datetime和timestamp都可以存儲相同類型的數據:時間和日期(精確到秒)。但是timestamp只花費前者一半的存儲空間。但是其允許的時間範圍稍小。

 

1.5 BIT 類型 

在mysql5.0 之前,bit相當於tinyint。在之後,bit在不同的存儲引擎上表現不同,在myisam上 bit就是使用對應長度字節存儲,而innodb和memorydb則使用足夠存儲bit位數的最小整數代替,無法減小開銷。

對於bit ,更奇怪的是它在不同上下文場景下的表現。在上文是字符串的場景下,查詢出的bit字段的 結果是一個 bit字段對應二進制值的ascii碼字符。但是如果在數字上下文,查詢出來的結果就會是數字。

例如

create table bittest (a bit(8));
insert into bittest a values(b'00111001');
select a ,a+0 from bittest;
最終會得出以下結果(字符9的ascii碼爲57)
|---------------|
| a     |a +0   |
-----------------
|  9    |  57   |

 

應儘量避免使用BIT。

 

1.6   主鍵  id 字段的 選用

   1.  數字 始終是最適合id的類型,因爲他們足夠快

  2.  字符串  

      避免字符串作爲id標識符,因爲它們比數字開銷更大,且更慢。尤其是在myisam中,myisam默認會對字符串使用壓縮索引,這會導致查詢慢很多。

    對於完全隨機的字符串,如uuid等,會任意分佈在很大的空間內,使得insert以及一些select  變得更慢。

(優點在寫的特別大的表可以消除熱點)

如果存儲uuid ,應該去除中間的 ‘-’ 字符。

一方面是由於主鍵字段過長,二是由於頁分裂和碎片導致的。在innoDB中,會根據主鍵去做聚簇索引,把索引和對應的數據行存儲的在葉子頁上,使用uuid寫入是無序的,InnoDB爲了數據的寫入,只能不斷頻繁的進行頁分裂操作,以便爲新的行分配空間。 由於頻繁的頁分裂,會導致頁變得稀疏被不規則的填充,所以最終導致產生了大量的數據碎片。

uuid適合數據量龐大、分佈式等特點的數據庫設計。

 

 

  mysql 限制每個關聯操作最多61個表

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章