MySQL優化-2-數據庫對象

優化表的數據類型 - PROCEDURE ANALYSE()
表須要使用何種數據類型,是須要根據應用來判斷的。雖然應用設計的時候須要考慮字段的長度留有必定的冗餘,可是不推薦讓不少字段都留有大量的冗餘,這樣即浪費存儲也浪費內存。咱們可使用PROCEDURE ANALYSE()對當前已有應用的表類型的判斷,該函數能夠對數據表中的列的數據類型提出優化建議,能夠根據應用的實際狀況酌情考慮是否實施優化。
語法:
SELECT * FROM tbl_name PROCEDURE ANALYSE();
SELECT * FROM tbl_name PROCEDURE ANALYSE(16,256);
輸出的每一列信息都會對數據表中的列的數據類型提出優化建議。第二個例子告訴PROCEDURE ANALYSE()不要爲那些包含的值多於16 個或者256 字節的ENUM 類型提出建議。若是沒有這樣的限制,輸出信息可能很長;ENUM 定義一般很難閱讀。
在對字段類型進行優化時,能夠根據統計信息並結合應用的實際狀況對其進行優化。

經過拆分提升表的訪問效率:
這裏咱們所說的拆分,主要是針對Myisam 類型的表,拆分的方法能夠分紅兩種狀況:
1. 縱向拆分:
縱向拆分是隻按照應用訪問的頻度,將表中常常訪問的字段和不常常訪問的字段拆分紅兩個表,常常訪問的字段儘可能是定長的,這樣能夠有效的提升表的查詢和更新的效率。
2. 橫向拆分:
橫向拆分是指按照應用的狀況,有目的的將數據橫向拆分紅幾個表或者經過分區分到多個分區中,這樣能夠有效的避免Myisam 表的讀取和更新致使的鎖問題。

逆規範化:
數據庫德規範化設計強調數據的獨立性,數據應該儘量少地冗餘,由於存在過多的冗餘數據,這就意味着要佔用了更多的物理空間,同時也對數據的維護和一致性檢查帶來了問題。
可是對於查詢操做不少的應用,一次查詢可能須要訪問多表進行,若是經過冗餘紀錄在相同表中,更新的代價增長很少,可是查詢操做效率能夠有明顯提升,這種狀況就能夠考慮經過冗餘數據來提升效率。

使用冗餘統計表:
使用create temporary table 語法,它是基於session 的表,表的數據保存在內存裏面,當session 斷掉後,表天然消除。對於大表的統計分析,若是統計的數據量不大,利用insert。。。select 將數據移到臨時表中比直接在大表上作統計要效率更高。

選擇更合適的表類型:
一、若是應用出現比較嚴重的鎖衝突,請考慮是否更改存儲引擎到innodb,行鎖機制能夠有效的減小鎖衝突的出現。
二、若是應用查詢操做不少,且對事務完整性要求不嚴格,則能夠考慮使用Myisam存儲引擎。更多存儲引擎選擇的原則,請參考開發篇的相關章節。

選擇mysql 存儲引擎
mysql的存儲引擎包括:MyISAM、InnoDB、BDB、MEMORY、MERGE、EXAMPLE、NDB Cluster、ARCHIVE、CSV、BLACKHOLE、FEDERATED等,其中InnoDB和BDB提供事務安全表,其餘存儲引擎都是非事務安全表。
 
最常使用的2 種存儲引擎:
1. Myisam存儲引擎。每一個MyISAM在磁盤上存儲成三個文件, 文件名都和表名相同,擴展名分別是.frm(存儲表定義)、.MYD (MYData,存儲數據)、.MYI (MYIndex,存儲索引)。數據文件和索引文件能夠放置在不一樣的目錄,平均分佈io,得到更快的速度。
2. InnoDB 存儲引擎提供了具備提交、回滾和崩潰恢復能力的事務安全。可是對比Myisam的存儲引擎,InnoDB 寫的處理效率差一些而且會佔用更多的磁盤空間以保留數據和索引。
注: MySQL以前是MyISAM爲默認存儲引擎,5.5後是InnoDB爲默認存儲引擎。

如何選擇合適的存儲引擎:
1) MyISAM:MySQL 插件式存儲引擎,它是在Web、數據倉儲和其餘應用環境下最常使用的存儲引擎之一.
2) InnoDB:用於事務處理應用程序,具備衆多特性,包括ACID 事務支持。
3) Memory:將全部數據保存在RAM 中,在須要快速查找引用和其餘相似數據的環境下,可提供極快的訪問。
4) Merge:容許MySQL DBA 或開發人員將一系列等同的MyISAM 表以邏輯方式組合在一塊兒,並做爲1 個對象引用它們。對於諸如數據倉儲等VLDB 環境十分適合。

選擇合適的數據類型
選擇原則-根據選定的存儲引擎,肯定如何選擇合適的數據類型.
1) MyISAM 數據存儲引擎和數據列: MyISAM數據表,最好使用固定長度的數據列代替可變長度的數據列。
2) MEMORY存儲引擎和數據列: MEMORY數據表目前都使用固定長度的數據行存儲,所以不管使用CHAR或VARCHAR列都沒有關係。二者都是做爲CHAR類型處理的。
3) InnoDB 存儲引擎和數據列: 建議使用VARCHAR類型. 對於InnoDB數據表,內部的行存儲格式沒有區分固定長度和可變長度列(全部數據行都使用指向數據列值的頭指針),所以在本質上,使用固定長度的CHAR列不必定比使用可變長度VARCHAR列簡單。於是,主要的性能因素是數據行使用的存儲總量。因爲CHAR平均佔用的空間多於VARCHAR,所以使用VARCHAR來最小化須要處理的數據行的存儲總量和磁盤I/O是比較好的。

1. CHAR 和VARCHAR 
它們類型相似,但它們保存和檢索的方式不一樣。
CHAR(4) 存儲需求 VARCHAR(4) 存儲需求
'' ' '  4 個字節 '' 1 個字節
'ab' 'ab ' 4 個字節 'ab ' 3 個字節
'abcd'  'abcd' 4 個字節 'abcd' 5個字節
'abcdefgh' 'abcd' 4 個字節 'abcd' 5個字節
請注意上表中最後一行的值只適用不使用嚴格模式時;若是MySQL 運行在嚴格模式,超過列長度的值不但不保存,而且會出現錯誤。
從CHAR(4)和VARCHAR(4)列檢索的值並不老是相同,由於從CHAR 列檢索時會刪除尾部的空格,而Varchar類型檢索時會保存尾部空格。 

2. TEXT和BLOB
在使用text 和blob 字段類型時要注意如下幾點,以便更好的發揮數據庫的性能.
1. BLOB和TEXT值會引發本身的一些問題,特別是執行了大量的刪除或更新操做的時候。刪除這種值會在數據表中留下很大的"空洞",之後填入這些"空洞"的記錄可能長度不一樣,爲了提升性能,建議按期使用OPTIMIZE TABLE 功能對這類表進行碎片整理.
2. 使用合成的(synthetic)索引。合成的索引列在某些時候是有用的。一種辦法是根據其它的列的內容創建一個散列值,並把這個值存儲在單獨的數據列中。接下來你就能夠經過檢索散列值找到數據行了。可是,咱們要注意這種技術只能用於精確匹配的查詢(散列值對於相似<或>=等範圍搜索操做符是沒有用處的)。咱們可使用MD5()函數生成散
列值,也可使用SHA1()或CRC32(),或者使用本身的應用程序邏輯來計算散列值。請記住數值型散列值能夠很高效率地存儲。一樣,若是散列算法生成的字符串帶有尾部空格,就不要把它們存儲在CHAR或VARCHAR列中,它們會受到尾部空格去除的影響。合成的散列索引對於那些BLOB或TEXT數據列特別有用。用散列標識符值查找的速度比搜索BLOB列自己的速度快不少。
3. 在沒必要要的時候避免檢索大型的BLOB或TEXT值。例如,SELECT *查詢就不是很好的想法,除非你可以肯定做爲約束條件的WHERE子句只會找到所須要的數據行。不然,你可能毫無目的地在網絡上傳輸大量的值。這也是BLOB或TEXT標識符信息存儲在合成的索引列中對咱們有所幫助的例子。你能夠搜索索引列,決定那些須要的數據行,而後從合格的數據行中檢索BLOB或TEXT值。
4. 把BLOB或TEXT列分離到單獨的表中。在某些環境中,若是把這些數據列移動到第二張數據表中,可讓你把原數據表中的數據列轉換爲固定長度的數據行格式,那麼它就是有意義的。這會減小主表中的碎片,使你獲得固定長度數據行的性能優點。它還使你在主數據表上運行SELECT *查詢的時候不會經過網絡傳輸大量的BLOB或TEXT值。

3. 浮點數與定點數
在mysql 中float、double(或real)是浮點數,decimal(或numberic)是定點數。
浮點數相對於定點數的優勢是在長度必定的狀況下, 浮點數可以表示更大的數據範圍;它的缺點是會引發精度問題。
在從此關於浮點數和定點數的應用中,你們要記住如下幾點:
一、浮點數存在偏差問題;從上面的例子中咱們看到c1 列的值由131072.32 變成了131072.31. 
二、對貨幣等對精度敏感的數據,應該用定點數表示或存儲;
三、編程中,若是用到浮點數,要特別注意偏差問題,並儘可能避免作浮點數比較;
四、要注意浮點數中一些特殊值的處理。
選擇合適的字符集
字符集是一套符號和編碼的規則,並且若是在數據庫建立階段沒有正確選擇字符集,那麼可能在後期須要更換字符集,而字符集的更換是代價比較高的操做,也存在必定的風險,因此,咱們推薦在應用開始階段,就按照需求正確的選擇合適的字符集,避免後期沒必要要的調整。

MySQL 支持的字符集
mysql服務器能夠支持多種字符集(能夠用show character set命令查看全部mysql支持的字符集),在同一臺服務器、同一個數據庫、甚至同一個表的不一樣字段均可以指定使用不一樣的字符集,相比oracle等其餘數據庫管理系統,在同一個數據庫只能使用相同的字符集,mysql明顯存在更大的靈活性。
mysql的字符集包括字符集(CHARACTER)和校對規則(COLLATION)兩個概念。字符集是用來定義mysql存儲字符串的方式,校對規則則是定義了比較字符串的方式。字符集和校對規則是一對多的關係, MySQL支持30多種字符集的70多種校對規則。每一個字符集至少對應一個校對規則。能夠用SHOW COLLATION LIKE 'utf8%';命令查看相關字符集的校對規則。

怎樣選擇合適的字符集
咱們建議在可以徹底知足應用的前提下,儘可能使用小的字符集。由於更小的字符集意味着可以節省空間、減小網絡傳輸字節數,同時因爲存儲空間的較小間接的提升了系統的性能。
有不少字符集能夠保存漢字,好比utf八、gb23十二、gbk、latin1 等等,可是經常使用的是gb2312 和gbk。由於gb2312 字庫比gbk 字庫小,有些偏僻字(例如:洺)不能保存,所以在選擇字符集的時候必定要權衡這些偏僻字在應用出現的概率以及形成的影響,不能作出確定答覆的話最好選用gbk。

MySQL 字符集的設置
mysql 的字符集和校對規則有4 個級別的默認設置:服務器級、數據庫級、表級和字段級。分別在不一樣的地方設置,做用也不相同。服務器字符集和校對,在mysql 服務啓動的時候肯定。
  • 能夠在my.cnf 中設置:[mysqld] default-character-set=utf8
  • 或者在啓動選項中指定:mysqld --default-character-set=utf8
  • 或者在編譯的時候指定:./configure --with-charset=utf8
若是沒有特別的指定服務器字符集,默認使用latin1 做爲服務器字符集。上面三種設置的方式都只指定了字符集,沒有指定校對規則,這樣是使用該字符集默認的校對規則,若是要使用該字符集的非默認校對規則,則須要在指定字符集的同時指定校對規則。能夠用show variables like 'character_set_server';命令查詢當前服務器的字符集和校對規則。
相關文章
相關標籤/搜索