MySQL加速查詢速度的獨門武器:查詢快取(QueryCache)
與朋友或同事談到mysql查詢快取功能的時候,個人喜歡把Query Cache比作荔枝,是非常營養的東西,但是一次性吃太多了,就容易導致上火而流鼻血,雖然不是特別恰當的比喻,但是有很多相似的地方,另外Query Cache有其特殊的業務場景,也不像其他資料庫產品,快取查詢語句的執行計劃等資訊,而是直接快取查詢語句的記錄集和對應的SQL語句。本文就給大家介紹下查詢快取的相關知識,希望可以引導大家正確地使用Query Cache這個獨門武器。
對mysql查詢快取從五個角度進行詳細的分析:Query Cache的工作原理、如何配置、如何維護、如何判斷查詢快取的效能、適合的業務場景分析。
n 工作原理
定義:
當mysql接收到一條select型別的query時,mysql會對這條query進行hash計算而得到一個hash值,然後通過該hash值到query cache中去匹配,如果沒有匹配中,則將這個hash值存放在一個hash連結串列中,同時將query的結果集存放進cache中,存放hash值的連結串列的每一個hash節點存放了相應query結果集在cache中的地址,以及該query所涉及到的一些table的相關資訊;如果通過hash值匹配到了一樣的query,則直接將cache中相應的query結果集返回給客戶端。如果mysql任何一個表中的任何一條資料發生了變化,便會通知query cache需要與該table相關的query的cache全部失效,並釋放佔用的記憶體地址
查詢快取的工作原理,基本上可以用二句話概括:
l 快取SELECT操作或預處理查詢(註釋:5.1.17開始支援)的結果集和SQL語句;
l 新的SELECT語句或預處理查詢語句,先去查詢快取,判斷是否存在可用的記錄集,判斷標準:與快取的SQL語句,是否完全一樣,區分大小寫;
查詢快取對什麼樣的查詢語句,無法快取其記錄集,大致有以下幾類:
l 查詢語句中加了SQL_NO_CACHE引數;
l 查詢語句中含有獲得值的函式,包涵自定義函式,如:CURDATE()、GET_LOCK()、RAND()、CONVERT_TZ等;
l 對系統資料庫的查詢:mysql、information_schema
l 查詢語句中使用SESSION級別變數或儲存過程中的區域性變數;
l 查詢語句中使用了LOCK IN SHARE MODE、FOR UPDATE的語句
l 查詢語句中類似SELECT …INTO 匯出資料的語句;
l 事務隔離級別為:Serializable情況下,所有查詢語句都不能快取;
l 對臨時表的查詢操作;
l 存在警告資訊的查詢語句;
l 不涉及任何表或檢視的查詢語句;
l 某使用者只有列級別許可權的查詢語句;
查詢快取的優缺點:
l 不需要對SQL語句做任何解析和執行,當然語法解析必須通過在先,直接從Query Cache中獲得查詢結果;
l 查詢快取的判斷規則,不夠智慧,也即提高了查詢快取的使用門檻,降低其效率;
l Query Cache的起用,會增加檢查和清理Query Cache中記錄集的開銷,而且存在SQL語句快取的表,每一張表都只有一個對應的全域性鎖;
n 配置
是否啟用mysql查詢快取,可以通過2個引數:query_cache_type和query_cache_size,其中任何一個引數設定為0都意味著關閉查詢快取功能,但是正確的設定推薦query_cache_type=0。
l query_cache_type
值域為:0 -– 不啟用查詢快取;
值域為:1 -– 啟用查詢快取,只要符合查詢快取的要求,客戶端的查詢語句和記錄集鬥可以快取起來,共其他客戶端使用;
值域為:2 -– 啟用查詢快取,只要查詢語句中新增了引數:SQL_CACHE,且符合查詢快取的要求,客戶端的查詢語句和記錄集,則可以快取起來,共其他客戶端使用;
l query_cache_size
允許設定query_cache_size的值最小為40K,對於最大值則可以幾乎認為無限制,實際生產環境的應用經驗告訴我們,該值並不是越大,查詢快取的命中率就越高,也不是對伺服器負載下降貢獻大,反而可能抵消其帶來的好處,甚至增加伺服器的負載,至於該如何設定,下面的章節講述,推薦設定為:64M;
l query_cache_limit
限制查詢快取區最大能快取的查詢記錄集,可以避免一個大的查詢記錄集佔去大量的記憶體區域,而且往往小查詢記錄集是最有效的快取記錄集,預設設定為1M,建議修改為16k~1024k之間的值域,不過最重要的是根據自己應用的實際情況進行分析、預估來設定;
l query_cache_min_res_unit
設定查詢快取分配記憶體的最小單位,要適當地設定此引數,可以做到為減少記憶體塊的申請和分配次數,但是設定過大可能導致記憶體碎片數值上升。預設值為4K,建議設定為1k~16K
l query_cache_wlock_invalidate
該引數主要涉及MyISAM引擎,若一個客戶端對某表加了寫鎖,其他客戶端發起的查詢請求,且查詢語句有對應的查詢快取記錄,是否允許直接讀取查詢快取的記錄集資訊,還是等待寫鎖的釋放。預設設定為0,也即允許;
n 維護
l 查詢快取區的碎片整理
查詢快取使用一段時間之後,一般都會出現記憶體碎片,為此需要監控相關狀態值,並且定期進行記憶體碎片的整理,碎片整理的操作語句:FLUSH QUERY CACHE;
l 清空查詢快取的資料
那些操作操作可能觸發查詢快取,把所有快取的資訊清空,以避免觸發或需要的時候,知道如何做,二類可觸發查詢快取資料全部清空的命令:
(1). RESET QUERY CACHE;
(2). FLUSH TABLES;
n 效能監控
l 碎片率
查詢快取記憶體碎片率=Qcache_free_blocks / Qcache_total_blocks * 100%
l 命中率
查詢快取命中率=Qcache_hits/(Qcache_hits + Qcache_inserts) * 100%
l 記憶體使用率
查詢快取記憶體使用率=(query_cache_size – Qcache_free_memory) / query_cache_size * 100%
l Qcache_lowmem_prunes
該引數值對於檢測查詢快取區的記憶體大小設定是否,有非常關鍵性的作用,其代表的意義為:查詢快取去因記憶體不足而不得不從查詢快取區刪除的查詢快取資訊,刪除演算法為LRU;
l query_cache_min_res_unit
記憶體塊分配的最小單元非常重要,設定過大可能增加記憶體碎片的概率發生,太小又可能增加記憶體分配的消耗,為此在系統平穩執行一個階段性後,可參考公式的計算值:
查詢快取最小記憶體塊 = (query_cache_size – Qcache_free_memory) / Qcache_queries_in_cache
l query_cache_size
我們如何判斷query_cache_size是否設定過小,依然也只有先預設定一個值,推薦為:32M~128M之間的區域,待系統平穩執行一個時間段(至少1周),並且觀察這周內的相關狀態值:
(1). Qcache_lowmem_prunes;
(2). 命中率;
(3). 記憶體使用率;
若整個平穩執行期監控獲得的資訊,為命中率高於80%,記憶體使用率超過80%,並且Qcache_lowmem_prunes的值不停地增加,而且增加的數值還較大,則說明我們為查詢緩衝區分配的記憶體過小,可以適當地增加查詢快取區的記憶體大小;
若是整個平穩執行期監控獲得的資訊,為命中率低於40%,Qcache_lowmem_prunes的值也保持一個平穩狀態,則說明我們的查詢緩衝區的記憶體設定過大,或者說業務場景重複執行一樣查詢語句的概率低,同時若還監測到一定量的freeing items,那麼必須考慮把查詢快取的記憶體條小,甚至關閉查詢快取功能;
n 業務場景
通過上述的知識梳理和分析,我們至少知道查詢快取的以下幾點:
l 查詢快取能夠加速已經存在快取的查詢語句的速度,可以不用重新解析和執行而獲得正確得記錄集;
l 查詢快取中涉及的表,每一個表物件都有一個屬於自己的全域性性質的鎖;
l 表若是做DDL、FLUSH TABLES 等類似操作,觸發相關表的查詢快取資訊清空;
l 表物件的DML操作,必須優先判斷是否需要清理相關查詢快取的記錄資訊,將不可避免地出現鎖等待事件;
l 查詢快取的記憶體分配問題,不可避免地產生一些記憶體碎片;
l 查詢快取對是否是一樣的查詢語句,要求非常苛刻,而且還不智慧;
我們再重新回到本節的重點上,查詢快取適合什麼樣的業務場景呢?只要是清楚了查詢快取的上述優缺點,就不難羅列出來,業務場景要求:
l 整個系統以讀為主的業務,比如門戶型、新聞類、報表型、論壇等網站;
l 查詢語句操作的表物件,非頻繁地進行DML操作,可以使用query_cache_type=2模式,然後SQL語句加SQL_CACHE引數指定;
本文來自:
文章地址MySQL加速查詢速度的獨門武器:查詢快取來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/26855487/viewspace-755169/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- mysql的查詢快取說明MySql快取
- mysql查詢快取簡單使用MySql快取
- Mysql 查詢快取 query_cacheMySql快取
- MySQL查詢快取引數詳解MySql快取
- mybatis入門基礎(八)-----查詢快取MyBatis快取
- 方法快取與查詢快取
- MySQL的查詢快取功能何時該開啟MySql快取
- ClickHouse為什麼查詢速度快?
- hibernate的查詢快取薦快取
- redis 快取 singlefly 查詢Redis快取
- MySQL查詢擷取分析MySql
- MySQL 4.1.0 中文參考手冊 --- 6.9 MySQL 查詢快取 (轉)MySql快取
- 想要批次查詢快遞,怎麼操作可以一鍵快速查詢物流資訊
- MySQL入門系列:查詢簡介(五)之子查詢MySql
- hibernate的查詢快取和二級快取的配合使用快取
- 找出Mysql查詢速度慢的SQL語句MySql
- 查詢快取(query_cache)的影響快取
- 海量資料的查詢快取問題快取
- 提高sql查詢速度SQL
- 提高count查詢速度
- 如何將 MySQL 查詢速度提升 300 倍MySql
- day03-商家查詢快取02快取
- MySQL入門系列:查詢簡介(七)之組合查詢MySql
- mysql查詢中時間、日期加減計算MySql
- mysql加強(3)~分組(統計)查詢MySql
- MySQL查詢取別名報錯MySql
- MySQL中in(獨立子查詢)的執行計劃MySql
- 快遞到哪了怎麼查詢?有上百單怎麼樣可以快速查詢?
- 優化sql查詢速度優化SQL
- 提高查詢速度使用materizlizedZed
- Access查詢實現Mysql的 limit 查詢MySqlMIT
- 微服務複雜查詢之快取策略微服務快取
- day02-2-商鋪查詢快取快取
- 老司機使用 Redis 快取複雜查詢Redis快取
- 小米手機如何用運單號碼查詢快遞資訊 小米手機快速查詢快遞資訊方法
- Mysql第十日字符集,XA事務,查詢快取MySql快取
- MySQL查詢MySql
- mysql-分組查詢-子查詢-連線查詢-組合查詢MySql