Mysql查詢全過程

在這裏插入圖片描述

  1. 客戶端發送一個查詢給服務器。
  2. 服務器先檢查查詢緩存,如果命中,則直接返回緩存中的結果。如果沒有沒有命中,則進入下一階段(解析器)。
  3. 服務器由解析器檢查sql語法是否正確,然後由預處理器檢查sql中的表和字段是否存在,最後由查詢優器生成執行計劃。這一步很耗資源。
  4. mysql根據優化器生成的執行計劃,調用存儲引擎的API來執行查詢。
  5. 將結果返回給客戶端。

MySQL客戶端和服務器之間的通信

  1. 在mysql服務器和客戶端之間的通信時“半雙工”的。就是在同一時刻要麼由客戶向Mysql服務器發送數據,要麼由MySQL服務器向客戶端發送數據。就像來回拋球遊戲,任何時候只有一個人能控制球,而且只有控制球的人才能將球拋出去(發送消息)。
  2. 當客戶端從MySQL服務器獲取數據時,看起來像像是客戶端向MySQL服務器拉取數據,但實際上是MySQL服務器向客戶端推送數據。客戶端不斷的接受從服務推送過來的數據,客戶端也沒有辦法讓服務器停下來。
  3. 大多數連接MySQL的庫函數都可以獲取全部的結果集並緩存到內存中。MySQL通常需要等到數據全部推送給客戶端後才能釋放這條語句查詢所暫用的資源。

查詢緩存

對執行計劃的緩存

對於很多的數據庫系統都能夠緩存執行計劃,對於完全相同的sql,可以使用已經已經存在的執行計劃,從而跳過解析和生成執行計劃的過程。
對完整的select查詢結果的緩存

查詢緩存的工作機制

Mysql 判斷是否命中緩存的辦法很簡單,首先會將要緩存的結果放在引用表中,然後使用查詢語句,數據庫名稱,客戶端協議的版本等因素算出一個hash值,這個hash值與引用表中的結果相關聯。如果在執行查詢時,根據一些相關的條件算出的hash值能與引用表中的數據相關聯,則表示查詢命中通過have_query_cache服務器系統變量指示查詢緩存是否可用:

mysql> SHOW VARIABLES LIKE ‘have_query_cache’;

變量名 值
Variable_name Value
have_query_cache YES
爲了監視查詢緩存性能,使用SHOW STATUS查看緩存狀態變量:

mysql> SHOW STATUS LIKE ‘Qcache%’;

變量名 值
Qcache_free_blocks 36
Qcache_free_memory 138488
Qcache_hits 79570
Qcache_inserts 27087
Qcache_lowmem_prunes 3114
Qcache_not_cached 22989
Qcache_queries_in_cache 415
Qcache_total_blocks 912
查詢緩存機制失效的場景

如果查詢語句中包含一些不確定因素時(例如包含函數Current()),該查詢不會被緩存,不確定因素主要包含以下情況。

引用了一些返回值不確定的函數
函數名 函數名 函數名 函數名
BENCHMARK() CONNECTION_ID() CURDATE() CURRENT_DATE()
CURRENT_TIME() CURRENT_TIMESTAMP() CURTIME() DATABASE()
帶一個參數的ENCRYPT() FOUND_ROWS() GET_LOCK() LAST_INSERT_ID()
LOAD_FILE() MASTER_POS_WAIT() NOW() RAND()
RELEASE_LOCK() SYSDATE() 不帶參數的UNIX_TIMESTAMP() USER()
引用自定義函數(UDFs)。
引用自定義變量
引用mysql系統數據庫中的表。
引用臨時表
引用存儲函數
任何包含列級別權限的表
不使用任何表

下面方式中的任何一種:
在這裏插入圖片描述
查詢緩存的額外的消耗

如果使用查詢緩存,在進行讀寫操作時會帶來額外的資源消耗,消耗主要體現在以下幾個方面:

查詢的時候會檢查是否命中緩存,這個消耗相對較小
如果沒有命中查詢緩存,MYSQL會判斷該查詢是否可以被緩存,而且系統中還沒有對應的緩存,則會將其結果寫入查詢緩存
如果一個表被更改了,那麼使用那個表的所有緩衝查詢將不再有效,並且從緩衝區中移出。這包括那些映射到改變了的表的使用MERGE表的查詢。一個表可以被許多類型的語句更改,例如INSERT、UPDATE、DELETE、TRUNCATE、ALTER TABLE、DROP TABLE或DROP DATABASE。
對於InnoDB而言,事物的一些特性還會限制查詢緩存的使用。當在事物A中修改了B表時,因爲在事物提交之前,對B表的修改對其他的事物而言是不可見的。爲了保證緩存結果的正確性,InnoDB採取的措施讓所有涉及到該B表的查詢在事物A提交之前是不可緩存的。如果A事物長時間運行,會嚴重影響查詢緩存的命中率

查詢緩存的空間不要設置的太大。

因爲查詢緩存是靠一個全局鎖操作保護的,如果查詢緩存配置的內存比較大且裏面存放了大量的查詢結果,當查詢緩存失效的時候,會長時間的持有這個全局鎖。因爲查詢緩存的命中檢測操作以及緩存失效檢測也都依賴這個全局鎖,所以可能會導致系統僵死的情況。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章