資料型別的優化

2021-08-31 03:35:46 字數 4701 閱讀 9343

數字有兩種型別:整數(whole number)和實數(real number)。如果儲存整數,就可以使用這幾種整數型別:tinyint、smallint、 mediumint、int 或bigint,它們分別需要8、16、24、32 和64位儲存空間。它們的範圍為

− 2n

−1到2

n−1−

1-2^到2^-1

−2n−1到

2n−1

−1這裡的n是所需儲存空間的位數。

整數型別有可選的unsigned屬性,它表示不允許負數,並大致把正,上限提高了一倍。例如,tinyint uns igned儲存的範圍為0到255,而不是-127到128。

有符號(signed)和無符號(unsigned) 型別占用的儲存空間是一樣的,效能也一樣。因此可以根據實際情況採用合適的型別。

你的選擇將會決定mysql把資料儲存在記憶體中還是磁碟上。然而,整數運算通常使用64位bigint整數,即使是32位架構也如此。(一些聚合函式是例外,它們使用decimal或double進行計算。)

mysql還可以對整數型別定義寬度,比如int(11)。這對於大多數應用程式都是沒有意義的:它不會限制值的範圍,只規定了mysql的互動工具(例如命令列客戶端)用來顯示字元的個數。對於儲存和計算,int(1)和int (20)是一樣的。

實數有分數部分。然而,它們並不僅僅是分數。可以使用decimal儲存比bigint還大的整數。mysql同時支援精確與非精確型別。

float和double 型別支援使用標準的浮點運算進行近似計算。如果想知道浮點運算到底如何進行,則要研究平台浮點數的具體實現。

decimal型別用於儲存精確的小數。在mysql 5.0及以上版本,decimal型別支援精確的數**算。mysql4.1和早期版本對decimal值執行浮點運算,它會因為丟失精度而導致奇怪的結果。在這些mysql版本中,decimal僅僅是「儲存型別」。

在mysql5.0及以上版本中,伺服器自身進行了decimal運算,因為cpu並不支援對它進行直接計算。浮點運算會快一點,因為計算直接在cpu上進行。

可以定義浮點型別和decimal型別的精度。對於decimai列,可以定義小數點之前和之後的最大位數,這影響了所需的儲存空間。mysql 5.0和以上版本把數字儲存到了乙個二進位制字串中(每4個位元組儲存9個數字)。例如,decimal (18, 9)將會在小數點前後都儲存9位數字,總共使用9個位元組:小數點前4個位元組,小數點佔1個位元組,小數點後4個位元組。

mysql 5.0及以上版本中的decimal型別最多允許65個數字。在較早的版本中,decimal 最多可以有254個數字,並且儲存為未壓縮的字串(乙個數字佔乙個位元組)。然而,這些版本的mysql根本不能在計算中使用如此大的數字,因為decimal只是一種儲存格式。decimal 在計算時會被轉換為double型別。

可以用多種方式定義浮點數列的精度,它會導致mysql悄悄採用不同的資料型別,或者在儲存的時候進行圓整。這些精度定義符不是標準的,因此我們建議定義需要的型別,而不是精度。

比起decimal型別,浮點型別儲存同樣大小的值使用的空間通常更少。float 占用4個位元組。double占用8個位元組,而且精度更高、範圍更大。和整數一樣,你選擇的僅僅是儲存型別。mysql在內部對浮點型別使用double進行計算。

由於需要額外的空間和計算開銷,只有在需要對小數進行精確計算的時候才使用decimal,比如儲存金融資料

varchar和char型別

兩種主要的字串型別是varchar和char。不幸的是,很難確切地解釋這兩種型別是怎樣破儲存到磁碟或記憶體中的,因為具體實現依賴於儲存引擎(例如,falcon 幾乎對每種資料型別都用了自己的儲存格式)。這裡假設你使用的是innodb和或myisam。如果不是,請參考所使用的儲存引擎的文件。

先看看varchar和char是如何被儲存到磁碟上的。要知道儲存引擎可能會使用不同的方式把char和varchar型別儲存到記憶體中,並且伺服器從儲存引擎取回這些值的時候還可能會把它轉換為其他儲存格式。下面是兩種型別的比較:

varchar

**varchar儲存了可變長度的字串,是使用得最多的字串型別。**它能比固定長度型別占用更少的儲存空間,因為它只占用了自己需要的空間(也就是說較短的值占用的空間就較少)。例外情況是使用row_ format-fixed 建立的myisam表,它為每行使用固定長度的空間,可能會造成浪費。

**varchar使用額外的1到2位元組來儲存值的長度。**如果列的最大長度小於或等於255,則使用1位元組,否則就使用2位元組。假設使用latin1 字符集,varchar(10)將會占用il位元組的儲存空間。varchar (1000)則會占用1002位元組,因為需要2個位元組來儲存長度資訊。

**varchar能節約空間,所以對效能有幫助。**然而,由於行的長度是可變的,它們在更新的時候可能會發生變化,這會引起額外的工作。如果行的長度增加並不再適合於原始的位置時,具體的行為則會和儲存引擎相關。例如,myisam會把行拆開,innodb則可能進行分頁。另外的儲存引擎還可能不會在合適的位置更新資料。

當最大長度遠大於平均長度,並且很少發生更新的時候,通常適合使用varchar。這時候碎片就不會成為問題。還有當你使用複雜的字符集,比如utf-8時,它的每個字元都可能會占用不同的儲存空間。

在5.0及以上版本,無論是儲存還是取值,mysql都會保留字串末尾的空格。但是在4.1及之前的版本,這些空格會被去掉。

char

char是固定長度的。mysql總是為特定數量的字元分配足夠的空間。當儲存char值的時候,mysql會去掉任何末尾的空格。(在mysql4.1及之前版本,varchar也是如此。char 和varchar在邏輯上是一樣的,只是儲存格式不同。)進行比較的時候,空格會被填充到字串末尾。

**char在儲存很短的字串或長度近似相同的字串的時候很有用。**例如,char適合用儲存使用者密碼的mds雜湊值,它的長度總是一-樣的。對於經常改變的值,char 也好於varchar,因為固定長度的行不容易產生碎片。對於很短的列,char的效率也高於varchar。char(1) 字串對於單位元組字符集(注1)只會占用1個位元組,但是varchar(1)則會占用2個位元組,因為有1個位元組用來儲存長度資訊。

blob和text分別別以二進位制和字元形式儲存大量資料

事實上,它們各自有自己的資料型別家族:字元型別有ェ inytext、 smallt2xt、txt、 mediumtex和工 ongtext,進製型別有 tinyblob、 smallblob、blob、 mediomblob和 longblob。blob等同於 smallbldb,tex等同

於mal

不同, mysql把blob和text當成有實體的物件來處理。儲存引擘通常會特別地儲存它們。 innodb的時候會使用單獨的「外部」儲存區域來進行儲存。毎個值在行裡面都需要1到4位元組,並且還需

blob和text唯一的區別就是blob儲存的是二進位制資料,沒有字符集和排序規則,但是text有字符集和排序

mysl對blob和text列的排序方式和其他型別不同:它不會按照字串的完整長度進行排序,而只是按照max_soxt_1 ength規定的前若干個位元組進行排序。如果只按照開始的幾個字元排序,就可以減少

max_sort_1 ength的值或使用 order by substring( column,length)

mysql提供了兩種相似的資料型別: datetime和 timestamp。

datetime

這個型別能儲存大範圍的值,從2023年到2023年,精度為秒。它把日期和時間封裝到乙個格式為yyyymmddhhmmss i的整數中,與時區無關。它使用了8位元組儲存空間

在預設情況下, mysql以一種可排序的、清楚的格式顯示 datetime值,例如2008-01-16 22:37208.這種表示日期和時間的方式符合ansi標準

timestamp

就像它的名字一樣, timestamp型別保持了自2023年1月1日午夜(格林尼治標準時間)以來的秒數 它和unⅸ的時間數相同。 timestamp只使用了4位元組的儲存空間,因此它的範圍比 datetime小得多。它表示只能從2023年到2023年。 mysql提供了from_ unixtime()函式把unix時間藏轉換為日期,並提供錄入unix_timestamp()函式,把日期轉換為unix時間戳。

較新的 mysql版本按照 datetime格式化 timestamp的值,但是較老的 mysql不會在各個部分之間顯示任何標點符號。

timestamp顯示的值也依賴於時區。 mysql伺服器、作業系統及客戶端連線都有時區設定。

儲存0值的 timestamp實際顯示為美國東部時間1969-12-31 19:00:00,與格林尼治標準時間(gmt)相差5小時。

timestamp也有 datetime沒有的特殊性質。在預設情況下,如果插入的行沒有定義 timestamp列的值,mysql就會把它設定為當前時間(注3),在更新的時候,如果沒有顯式地定義 timestamp列的值, mysql 也會自動更新它。可以配置 timestamp列的插入和更新行為。最後, timestamp.列缺省是not null,這和其他的資料型別都不一樣

除了這些特殊行為之外,通常應該使用 timestamp,因為它比 datetime更節約空間。有時人們把unⅸ的時間戳儲存為整數值,但是這通常沒有任何好處。因為這種格式處理起來不太方便,我們並不推薦它。

如果需要以秒以下的精度儲存日期和時間,應該怎麼辦? mysql當前沒有適合的資料型別,但是可以使用自己的儲存格式:可以使用 bigint型別井且把它以毫秒的精度儲存為時間戳格式,或者使用 double儲存秒的分數部分。這兩種辦法都不錯。

資料型別優化

tinyint,smallint,mediumint,int,bigint 分別使用8,16,32,64,128位儲存空間,儲存的值範圍 2 2 1float,double,decimal doule和float使用標準的浮點運算進行近似計算,decimal用於儲存精確的小數 float佔4個位元組...

優化表的資料型別

我們可以使用procedure analyse 對當前已有應用的表型別的判斷,該函式可以對資料表中的列的資料型別提出優化建議,可以根據應用的實際情況酌情考慮是否實施優化。語法 select from tbl name procedure analyse select from tbl name pr...

MySQL資料型別優化

mysql資料型別眾多,選擇正確的資料型別對於獲得高效能至關重要。遵從以下幾條原則有助力做出更好的選擇。1 更小的資料型別。更小的資料型別通常更快,因為它們占用更少的磁碟 記憶體和cpu快取,並且處理時需要的cpu週期也更少。但也要確保自己沒有低估需要的儲存範圍。2 簡單的資料型別。簡單的資料型別通...