邏輯架構mysql
MySQL邏輯架構總體分爲三層:sql
存儲引擎數據庫
主要介紹InnoDB引擎和MyISAM引擎緩存
InnoDB引擎:安全
MyISAM引擎:服務器
查詢過程數據結構
咱們但願經過MySQL能夠得到更好的查詢性能,最好的方式就是弄清楚MySQL是如何執行查詢的,理解了這一點,咱們能夠依據它的規則去優化SQL語句。架構
當向MySQL發送一個SQL請求的時候,究竟發生了什麼呢,以下:併發
客戶端/服務端通訊協議數據庫設計
一、MySQL客戶端/服務端通訊協議是半雙工的:在任一時刻,要麼是服務器向客戶端發送數據,要麼是客戶端向服務器發送數據,這兩個動做不能同時發生。一旦一端開始發送消息,另外一端要接收完整個消息才能響應它,因此咱們沒法將一個消息切成小塊獨立發送,也沒有辦法進行流量控制。
二、客戶端用一個單獨的數據包將查詢請求發送給服務器,因此當查詢語句很長的時候,須要設置max_allowed_packet參數。可是須要注意的是,若是查詢實在是太大,服務端會拒絕接收更多數據並拋出異常。
三、服務器響應給用戶的數據一般會不少,由多個數據包組成。可是當服務器響應客戶端請求時,客戶端必須完整的接收整個返回結果,而不能只取部分結果,而後讓服務器中止發送。於是在實際開發中,儘可能保持查詢簡單且只返回必需的數據,減少通訊間數據包的大小和數量是一個很是好的習慣,這也是查詢中儘可能避免使用SELECT *以及加上LIMIT限制的緣由之一。
小結:請求語句有大小限制,不該過長;減少通訊間數據包大小及通訊數量
查詢緩存
在解析一個查詢語句前,若是查詢緩存是打開的,那麼MySQL會檢查這個查詢語句是否命中查詢緩存中的數據。若是當前查詢剛好命中查詢緩存,在檢查一次用戶權限後直接返回緩存中的結果。這種狀況下,查詢不會被解析,也不會生成執行計劃,更不會執行。
MySQL將緩存存放在一個引用表(相似於HashMap的數據結構),經過一個哈希值索引,這個哈希值經過查詢語句、查詢的數據庫、客戶端協議版本號等一些可能影響結果的信息計算得來。因此兩個查詢在任何字符上的不一樣(例如:空格、註釋),都會致使緩存不會命中。
若是查詢中包含任何用戶自定義函數、存儲函數、用戶變量、臨時表、mysql庫中的系統表,其查詢結果都不會被緩存。好比函數NOW()或者CURRENT_DATE()會由於不一樣的查詢時間,返回不一樣的查詢結果,再好比包含CURRENT_USER或者CONNECION_ID()的查詢語句會由於不一樣的用戶而返回不一樣的結果,將這樣的查詢結果緩存起來沒有任何的意義。
MySQL的查詢緩存系統會跟蹤查詢中涉及的每一個表,若是這些表(數據或結構)發生變化,那麼和這張表相關的全部緩存數據都將失效。正由於如此,在任何的寫操做時,MySQL必須將對應表的全部緩存都設置爲失效。若是查詢緩存很是大或者碎片不少,這個操做就可能帶來很大的系統消耗,甚至致使系統僵死一下子。
查詢緩存對系統的額外消耗不只僅在寫操做,讀操做也不例外:
不要輕易打開查詢緩存,特別是寫密集型應用。若是必定要開啓查詢緩存,能夠將query_cache_type設置爲DEMAND,只有查詢語句加入SQL_CACHE的查詢纔會走緩存,其餘查詢則不會,這樣能夠很是自由地控制哪些查詢須要被緩存。
語法解析和預處理
MySQL經過關鍵字將SQL語句進行解析,而且建立內部數據結構解析樹,這個過程解析器主要經過語法規則來驗證和解析,好比是否使用了錯誤的關鍵字,查詢的數據表和列是否存在等,而後對其進行各類優化,包括重寫查詢,決定表的讀寫順序,以及選擇合適的索引等。用戶能夠經過特殊的關鍵字提示(hint)優化器,影響它的決策過程。也能夠請求優化器解釋(explain)優化過程的各個因素,使用戶知道服務器如何進行優化決策的,這個比較實用,尤爲是優化某個查詢語句時。