日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

mysql query cache

發布時間:2023/12/19 数据库 16 豆豆
生活随笔 收集整理的這篇文章主要介紹了 mysql query cache 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

1.概述:

? ?MySQL Query Cache 緩存客戶端提交給MySQL的SELECT(注意只是select)語句以及該語句的結果集。

注意:query_cache是mysql server端的查詢緩存,在存儲引擎之上。存儲引擎層還有存儲引擎的緩存,表也有表的緩存,日志也有日志的緩存,還可以用nosql實現二級三級甚至更多層的緩存.....緩存是提高性能的上方寶劍,因為內存的速度比磁盤的速度要快的多的多,寧愿在內存中執行1000次也不在磁盤上執行一次,緩存可以跳過解析和優化的操作從而大幅度提高查詢性能。


更具體的可以看源碼sql/sql_cache.cc 。


2.mysql的Query Cache原理:

? ?客戶端的select語句通過一定的hash算法進行計算,存放在hash桶中,并對結果集存放在內存中,存放query hash值的鏈表中存放了hash值和結果集的內存地址和query涉及的所有table的標識等信息。前端的sql過來會先進行hash計算,如果能夠在cache中找到,就直接從內存中取出結果返回給前端,如果沒有則mysql解析器會對sql進行解析并且優化。注意查詢cache是在sql解析器前執行的,所有速度非常快,因為又省去了一個操作。


3.失效機制:

? ? 當后端任何一個表的一條數據,索引,結構發生變化時,就會將與此表關聯的query chache失效,并且釋放內存。所以對于數據變化頻繁的sql就不要cache了。那樣不但不會提高性能還能得到相反的結果,因為每次多了查詢緩存的操作。

? ? 這里要指出的是,這種失效機制并不科學,因為有些表的改動并不會導致結果集的改變。但是這種方法簡單,開銷也比較小。


4.相關設置參數:

SHOW VARIABLES LIKE '%query_cache%';


query_cache_limit:允許 Cache 的單條 Query 結果集的最大容量,默認是1MB,超過此參數設置的 Query 結果集將不會被 Cache

query_cache_min_res_unit:設置 Query Cache 中每次分配內存的最小空間大小,也就是每個 Query 的 Cache 最小占用的內存空間大小,默認4KB,要設置合理,不然會造成碎片過多,造成內存的浪費。

query_cache_size:設置 Query Cache 所使用的內存大小,默認值為0,大小必須是1024的整數倍,如果不是整數倍,MySQL 會自動調整降低最小量以達到1024的倍數

query_cache_type:控制 Query Cache 功能的開關,可以設置為0(OFF),1(ON)和2(DEMAND)三種,意義分別如下:

? ? ? ?0(OFF):關閉 Query Cache 功能,任何情況下都不會使用 Query Cache

? ? ? ?1(ON):開啟 Query Cache 功能,但是當 SELECT 語句中使用的 SQL_NO_CACHE 提示后,將不使用Query Cache

? ? ? ?2(DEMAND):開啟 Query Cache 功能,但是只有當 SELECT 語句中使用了 SQL_CACHE 提示后,才使用 Query Cache

query_cache_wlock_invalidate:控制當有寫鎖定發生在表上的時刻是否先失效該表相關的 Query Cache,如果設置為 1(TRUE),則在寫鎖定的同時將失效該表相關的所有Query Cache,如果設置為0(FALSE)則在鎖定時刻仍然允許讀取該表相關的 Query Cache。默認false


5.Query Cache 處理子查詢:
? ?Query Cache 是以客戶端請求提交的Query 為對象來處理的,只要客戶端請求的是一個Query,無論這個 Query 是一個簡單的單表查詢還是多表 Join,亦或者是帶有子查詢的復雜 SQL,都被當作成一個Query,不會被分拆成多個Query 來進行Cache。所以,存在子查詢的復雜Query 也只會產生一個Cache對象,子查詢不會產生單獨的Cache內容。UNION[ALL] 類型的語句也同樣如此。


6.Query Cache 導致性能反而下降的原因:
? ?1.開啟Query Cache并且query_cache_type 參數設置為1,或者是2但是緩存了太多的不必要sql,導致MySQL 對每個SELECT 語句都進行Query Cache 查找,這樣就比直接查找多一次查找緩存的操作;

? ?2.并且由于Query Cache 的失效機制的特性,比如表上的數據變化比較頻繁,大量的 Query Cache 頻繁的被失效,所以 Query Cache 的命中率就可能非常低;

? ?3.query_cache_min_res_unit設置不合理導致內存碎片太多;

? ?4.query cache 緩存的是結果集而不是數據頁,所以由于sql寫的不合理導致同一結果集的sql 被緩存多次,浪費內存。字符大小寫、空格或者注釋的不同,緩存都是認為是不同的sql(因為他們的hash值會不同)。

? ?5.對于Innodb,事務會讓緩存失效,當事務內的語句更改了表,即使Innodb的多版本機制隱藏了事務的變化,服務器也會使所有(不管事務內還是外)引用了該表的查詢緩存的哦偶失效,直到事務提交,所以經常使用事務或使 ?緩存的命中率下降。


所以有些場景下,Query Cache 不僅不能提高效率,反而可能造成負面影響。

從緩存中受益最大的查詢是需要很多資源產生得到的結果,并且變化不是很頻繁的。


7.Query cache帶來的額外開銷:

1.sql優化器在分析之前必須檢查緩存

? ?2.如果查詢是可以緩存,但是不在緩存中,那么產生結果后進行保存會帶來額外開銷

? ?3.寫入數據的查詢也會帶來而外開銷,因為他必須去檢查緩存中是否有相關sql,如果有得讓它失效。


8.確認系統的Query Cache 的使用情況,命中率:

show status like 'Qcache%' ;

? ?Qcache_free_blocks:目前還處于空閑狀態的 Query Cache 中內存 Block 數目

? ?Qcache_free_memory:目前還處于空閑狀態的 Query Cache 內存總量

? ?Qcache_hits:Query Cache 命中次數

? ?Qcache_inserts:向Query Cache 中插入新的 Query Cache 的次數,也就是沒有命中的次數

? ?Qcache_lowmem_prunes:Query Cache 因為內存不夠,而從中刪除老的Query Cache的次數。

? ?Qcache_not_cached:沒有被 Cache 的 SQL 數,包括無法被 Cache 的 SQL 以及由于 query_cache_type 設置的不會被 Cache 的 SQL

? ?Qcache_queries_in_cache:目前在 Query Cache 中的 SQL 數量

? ?Qcache_total_blocks:Query Cache 中總的 Block 數量


? ?Query Cache 命中率= Qcache_hits/(Qcache_hits+Qcache_inserts) ; Query Cache 的大小設置一般不要超過256MB。

? ?如果從查詢緩存中返回一個查詢結果,服務器把Qcache_hits狀態變量的值加一,而不是Com_select變量。


9.未命中緩存的情況:

? ?1.查詢不可緩存,比如包含不確定函數,比如current_date等。

? ?2.結果太大,超過了query_cache_limit的大小。

? ?3.由于內存空間不夠,被移除了。


10.MySQL Cluster 和 Query Cache:
? MYSQL 文檔中說明確實可以在 MySQL Cluster 中使用 Query Cache。這塊還需要繼續研究。


11.內存與碎片:

1.首先緩存自身大小為40K。mysql服務器自己管理自己的內存,不依賴于操作系統。

? ?2.服務器每次分配一個塊至少是query_cache_min_res_unit的大小,但它不能精確的分配,服務器不是在獲得所有結果才返回給客戶的,而是產生一行就發送一行,因為這樣的效率高,但結果是緩存的結果不精確。 ?

? ?3.flush query cache 移除緩存碎片,它會把所有的存儲塊向上移動,把空閑塊移動到底部,但它運行的時候,會阻塞訪問查詢緩存,鎖定整個服務器。該語句不從緩存中移出任何查詢。


12.Query cache的限制:

1.5.1.17之前的版本不能緩存cache綁定變量的query,從5.1.17開始支持。

? ?2.Procedure、function、Trigger、臨時表 、用戶有某個表的列級權限,的query不能被緩存。

? ?3.包含很多每次執行結果都不一樣的系統函數不能被緩存,比如:current_date()。如果你想讓他緩存,比如緩存今天的可以把current_date()的實際值賦予它。

? ?4.mysql5.1之前的準備語句也不能被緩存(prepared statement)。

? ?5.mysql, INFORMATION_SCHEMA相關表的查詢也不會被緩存。


12.其他相關:

SELECT查詢的總數量等價于:

Com_select+ Qcache_hits+ queries with errors found by parser


Com_select的值等價于:

Qcache_inserts+ Qcache_not_cached+ queries with errors found during columns/rights check


轉載于:https://blog.51cto.com/xqtesting/1376090

總結

以上是生活随笔為你收集整理的mysql query cache的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。