在很多客戶一起查詢數據表時,如果使客戶能最快地查詢到數據就是調度和鎖定做的工作了。在MySQL中,我們把select操作叫做讀,把對數據表修改增加的操作(INSERT,UPDATE,REPLACE...)叫做寫。MySQL的基本調度策略可以歸納為以下兩條:
寫入請求將按它們到達服務器的順序進行處理;
寫操作的優先級要高於讀操作。
MyISAM和ISAM數據表的調度策略是在數據表鎖的幫助下實現的,在客戶程序要訪問數據表之前,需獲得相應的鎖,在完成對數據表的操作後,再釋放該鎖。鎖的管理通常由服務器管理,也可人為地用LOCK TABLES和UNLOCK TABLES命令來申請和釋放鎖。寫操作時,需要申請一個獨占性的鎖,也就是說在寫操作其間,該表只能由寫操作的客戶使用。讀操作時,客戶必須申請一個允許其他客戶對數據表進行寫操作的鎖,以確保客戶在讀的過程中數據表不會發生改變。但讀操作鎖不是獨占的,可有多個讀操作同時作用於同一個數據表。
通過一些修飾符可影響調度策略,如LOW_PRIORITY(用於DELETE,INSERT,LOAD DATA,REPLACE,UPDATE語句)、HIGH_PRIORITY(用於SELECT語句)、DELAYED(用於INSERT和REPLACE語句)。它們的作用是這樣的:
LOW_PRIORITY會使寫操作的優先級降低到讀操作以下,也就是說讀操作會阻塞該級別的寫操作,SELECT的HIGH_PRIORITY有類似的作用。
INSERT語句中的DELAYED修飾會使插入操作被放入一個“延遲插入”隊列。並返回狀態信息給客戶,使客戶程序可在新數據行還沒插入到數據表之前繼續執行後面的操作。如果一直有客戶讀該數據表,新數據行會一直待在隊列中,直到數據表沒有讀操作時,服務器才會把隊列中的數據行真正插入到數據表中。該語句可用在以下場合,在一個有冗長查詢的數據表中插入數據,而你又不想被阻塞,你就可發出INSERT DELAYED語句,把插入操作放入服務器“延遲插入”隊列,你無需等待就馬上可進行接下來的操作。
當一個數據表裡從未進行過刪除操作或剛剛對它進行過碎片整理的情況下,用INSERT語句插入的數據行只會被添加到數據表的末尾,而不會插入到數據表的中間位置。這樣,對於MyISAM表,MySQL允許在有其它客戶正在讀操作的時間進行寫操作。我們稱之這並發插入。要使用該技巧,需注意以下兩個問題:
不要在INSERT語句中使用LOW_PRIORITY修飾符。
讀操作應用LOCK TABLES ... READ LOCAL而不是用LOCK TABLES ... READ語句來進行數據表讀鎖定。LOCAL關鍵字只對數據表中已存在行進行鎖定,不會阻塞把新行添加到數據表末尾。
BDB數據表使用頁面級操作鎖,InnoDB數據表使用數據行級操作鎖。所以這兩種表的並發性比MyISAM和ISAM數據表這種表級鎖的並發性會好很多。其中InnoDB的並發性最好。綜上所述,我們可得出以下結論:
MyISAM和ISAM數據表的檢索速度最快,但如果在檢索和修改操作較多的場合,會出鎖競爭的問題,造成等待時間延長。
BDB和InnoDB數據表能在有大量修改操作的環境下提供很好的並發性,從而提供更好的性能。
MyISAM和ISAM數據表由於進行表級鎖定,所以不會出現死鎖現象,BDB和InnoDB數據表則存在死鎖的可能性。