高效能MySql第三版 閱讀簡記 1

2021-10-05 02:25:22 字數 2831 閱讀 7887

mysql支援的資料型別非常多,選擇正確的資料型別對於獲得高效能至關重要。不管儲存哪種型別的資料,下面幾個簡單的原則都有助於做出更好的選擇。更小的通常更好。

一般情況下,應該盡量使用可以正確儲存資料的最小資料型別(1) 。更小的資料型別通常更快,因為它們占用更少的磁碟、記憶體和cpu快取,並且處理時需要的cpu週期也更少。

但是要確保沒有低估需要儲存的值的範圍,因為在schema中的多個地方增加資料型別的範圍是乙個非常耗時和痛苦的操作。如果無法確定哪個資料型別是最好的,就選擇你認為不會超過範圍的最小型別。(如果系統不是很忙或者儲存的資料量不多,或者是在可以輕易修改設計的早期階段,那之後修改資料型別也比較容易)。

簡單就好

簡單資料型別的操作通常需要更少的cpu週期。例如,整型比字元操作代價更低,因為字符集和校對規則(排序規則)使字元比較比整型比較更複雜。這裡有兩個例子:乙個是應該使用mysql內建的型別(2)而不是字串來儲存日期和時間,另外乙個是應該用整型儲存ip位址。稍後我們將專門討論這個話題。

盡量避免null

很多表都包含可為null(空值)的列,即使應用程式並不需要儲存null也是如此,這是因為可為null是列的預設屬性(3)。通常情況下最好指定列為notnull,除非真的需要儲存null值。

如果查詢中包含可為null的列,對mysql來說更難優化,因為可為null的列使得索引、索引統計和值比較都更複雜。可為null的列會使用更多的儲存空間,在mysql裡也需要特殊處理。當可為null的列被索引時,每個索引記錄需要乙個額外的位元組,在myisam裡甚至還可能導致固定大小的索引(例如只有乙個整數列的索引)變成可變大小的索引。

通常把可為null的列改為not null帶來的效能提公升比較小,所以(調優時)沒有必要首先在現有schema中查詢並修改掉這種情況,除非確定這會導致問題。但是,如果計畫在列上建索引,就應該盡量避免設計成可為null的列。

當然也有例外,例如值得一提的是,innodb使用單獨的位(bit)儲存null值,所以對於稀疏資料(4)有很好的空間效率。但這一點不適用於myisam。在為列選擇資料型別時,第一步需要確定合適的大型別:數字、字串、時間等。這通常是很簡單的,但是我們會提到一些特殊的不是那麼直觀的案例。下一步是選擇具體型別。很多mysql的資料型別可以儲存相同型別的資料,只是儲存的長度和範圍不一樣、允許的精度不同,或者需要的物理空間(磁碟和記憶體空間)不同。相同大型別的不同子型別資料有時也有一些特殊的行為和屬性。例如,datetime和timesamp列都可以儲存相同型別的資料:時間和日期,精確到秒。

然而timestamp只使用datetime一半的儲存空間,並且會根據時區變化,具有特殊的自動更新能力。另一方面,timestamp允許的時間範圍要小得多,有時候它的特殊能力會成為障礙。

有兩種型別的數字:整數(whole number)和實數(real number)。如果儲存整數,可以使用這幾種整數型別:tinyint,smallint,mediumint,int,bigint。分別使用8,16,24,32,64位儲存空間。它們可以儲存的值的範圍從−2(n−1)到2(n−1)−1,其中n是儲存空間的位數。

整數型別有可選的unsigned屬性,表示不允許負值,這大致可以使正數的上限提高一倍。例如tinyint unsigned可以儲存的範圍是0~255,而tinyint的儲存範圍是−128~127。

實數是帶有小數部分的數字。然而,它們不只是為了儲存小數部分;也可以使用decimal儲存比bigint還大的整數。mysql既支援精確型別,也支援不精確型別。

因為cpu不支援對decimal的直接計算,所以在mysql 5.0以及更高版本中,mysql伺服器自身實現了decimal的高精度計算。相對而言,cpu直接支援原生浮點計算,所以浮點運算明顯更快。

浮點和decimal型別都可以指定精度。對於decimal列,可以指定小數點前後所允許的最大位數。這會影響列的空間消耗。mysql 5.0和更高版本將數字打包儲存到乙個二進位制字串中(每4個位元組存9個數字)。例如,decimal(18,9)小數點兩邊將各儲存9個數字,一共使用9個位元組:小數點前的數字用4個位元組,小數點後的數字用4個位元組,小數點本身佔1個位元組。

因為需要額外的空間和計算開銷,所以應該盡量只在對小數進行精確計算時才使用decimal——例如儲存財務資料。但在資料量比較大的時候,可以考慮使用bigint代替decimal,將需要儲存的貨幣單位根據小數的位數乘以相應的倍數即可。假設要儲存財務資料精確到萬分之一分,則可以把所有金額乘以一百萬,然後將結果儲存在bigint裡,這樣可以同時避免浮點儲存計算不精確和decimal精確計算代價高的問題。

例如:如果我想儲存精確度以 "分" 為單位的數字."99.75元"

1.可以將資料庫中的列資料模型設計為: 

alter table demo_table add column_1 decimal(5,2) null;
譯:意思是新增一列小數點前可存放5位,小數點後可存放2位的數字;然後將"99.75"元直接存放進庫中

2.可以將資料庫中的列資料模型設計為: 

alter table demo_table add column_1 bigint(10) null;
譯:意思是新增一列較長的數字;並且在sql查詢/新增或者 在**中  將金錢乘以"100",得到"9975"然後存放庫中,取出時使用金錢除以100,換算成正確的金錢數額"99.75"; 

附錄:(1) 例如只需要存0~200,tinyint unsigned更好。——譯者注

(2) date,time,datatime——譯者注

(3) 如果定義表結構時沒有指定列為not null,預設都是允許為null的。

(4) 很多值為null,只有少數行的列有非null值。——譯者注

高效能MySql第三版 閱讀簡記 2

varchar和char型別 varchar和char是兩種最主要的字串型別。不幸的是,很難精確地解釋這些值是怎麼儲存在磁碟和記憶體中的,因為這跟儲存引擎的具體實現有關。下面的描述假設使用的儲存引擎是innodb和 或者myisam。如果使用的不是這兩種儲存引擎,請參考所使用的儲存引擎的文件。先看看...

高效能mysql第三版

高效能mysql第三版 本書目錄結構如下 第一章 mysql架構與歷史 1.1 mysql邏輯架構 1.2 開發控制 1.3 事務 1.4 多版本併發控制 1.5 mysql的儲存引擎 1.6 mysql時間線 timeline 1.7 mysql的開發模式 第二章 mysql基準測試 2.1 為什...

編譯apue 第三版

想要直接使用作者提供的源 就需要編譯下,這個檔名是src.3e.tar.gz 很簡單的幾步就搞定了.解壓src.3e.tar.gz 進入apue.3e make 進入apue.3e lib目錄,複製libapue.a到 usr local lib目錄 進入 apue.3e include目錄,複製 ...