mysql|最佳化
7 MySQL 最佳化
資料庫最佳化是一項很複雜的工作,因為這最終需要對系統最佳化的很好理解才行。儘管對系統或應用系統的瞭解不多的情況下最佳化效果還不錯,但是如果想最佳化的效果更好,那麼就需要對它瞭解更多才行。
本章主要講解了幾種最佳化MySQL的方法,並且給出了例子。記著,總有各種辦法能讓系統啟動並執行更快,當然了,這需要更多的努力。
7.1 最佳化概述
讓系統運行得快得最重要因素是資料庫基本的設計。並且還必須清楚您的系統要用來做什麼,以及存在的瓶頸。
最常見的系統瓶頸有以下幾種:
磁碟搜尋。它慢慢地在磁碟中搜尋資料區塊。對現代磁碟來說,平時的搜尋時間基本上小於10毫秒,因此理論上每秒鐘可以做100次磁碟搜尋。這個時間對於全新的新磁碟來說提高的不多,並且對於只有一個表的情況也是如此。加快搜尋時間的方法是將資料分開存放到多個磁碟中。
磁碟讀/寫。當磁碟在正確的位置上時,就需要讀取資料。對現代磁碟來說,磁碟輸送量至少是10-20MB/秒。這比磁碟搜尋的最佳化更容易,因為可以從多個媒介中並行地讀取資料。
CPU周期。資料存放區在主記憶體中(或者它已經在主記憶體中了),這就需要處理這些資料以得到想要的結果。存在多個?硐啾饒詿嬡萘坷此蹈竅拗頻囊蛩亍2還孕"砝此擔俁韌ǔ2皇俏侍狻?
記憶體頻寬。當CPU要將更多的資料存放在CPU緩衝中時,主記憶體的頻寬就是瓶頸了。在大多數系統中,這不是常見的瓶頸,不過也是要注意的一個因素。
7.1.1 MySQL 設計的局限性
當使用MyISAM儲存引擎時,MySQL會使用一個快速資料表鎖以允許同時多個讀取和一個寫入。這種儲存引擎的最大問題是發生在一個單一的表上同時做穩定的更新操作及慢速查詢。如果這種情況在某個表中存在,可以使用另一種表類型。詳情請看"15 MySQL Storage Engines and Table Types"。
MySQL可以同時在事務及非事務表下工作。為了能夠平滑的使用非事務表(發生錯誤時不能復原),有以下幾條規則:
所有的欄位都有預設值
如果欄位中插入了一個"錯誤"的值,比如在數字類型欄位中插入過大數值,那麼MySQL會將該欄位值置為"最可能的值"而不是給出一個錯誤。數字類型的值是0,最小或者最大的可能值。字串類型,不是Null 字元串就是欄位所能儲存的最大長度。
所有的計算運算式都會返回一個值而報告條件錯誤,例如 1/0 返回 NULL。
這些規則隱含的意思是,不能使用MySQL來檢查欄位內容。相反地,必須在儲存到資料庫前在應用程式中來檢查。詳情請看"1.8.6 How MySQL Deals with Constraints 和 "14.1.4 INSERT Syntax"。
7.1.2 應用設計的可移植性
由於各種不同的資料庫實現了各自的SQL標準,這就需要我們盡量使用可移植的SQL應用。查詢和插入操作很容易就能做到可移植,不過由於更多的約束條件的要求就越發困難。想要讓一個應用在各種資料庫系統上快速運行,就變得更困難了。
為了能讓一個複雜的應用做到可移植,就要先看這個應用運行於哪種資料庫系統之上,然後看這些資料庫系統都支援哪些特性。
每個資料庫系統都有某些不足。也就是說,由於設計上的一些妥協,導致了效能上的差異。
可以用MySQL的 crash-me 程式來看選定的資料庫伺服器上可以使用的函數,類型,限制等。crash-me 不會檢查各種可能存在的特性,不過這仍然是合乎情理的理解,大約做了450次測試。
一個 crash-me 的資訊類型的例子就是,它會告訴您如果想使用Informix 或 DB2的話,就不能使欄位名長度超過18個字元。
crash-me 程式和MySQL基準使每個准資料庫都實現了的。可以通過閱讀這些基準程式是怎麼寫的,自己就大概有怎樣做才能讓程式獨立於各種資料庫這方面的想法了。這些程式可以在MySQL原始碼的 `sql-bench' 目錄下找到。他們大部分都是用Perl寫的,並且使用DBI介面。由於它提供了獨立於資料庫的各種訪問方式,因此用DBI來解決各種移植性的問題。
想要看到 crash-me 的結果,可以訪問:http://dev.mysql.com/tech-resources/crash-me.php. 訪問 http://dev.mysql.com/tech-resources/benchmarks 可以看到基準的結果。