《MySQL面試小抄》查詢緩存機制終面
我是肥哥,一名不專業的面試官!
我是囧囧,一名積極找工作的小菜鳥!
囧囧表示:小白面試最怕的就是面試官問的知識點太籠統,自己無法快速定位到關鍵問題點!!!
本期主要面試考點
面試官考點之簡述一下什麼是查詢緩存機制?
面試官考點之查詢如何命中緩存?
面試官考點之什麼場景下SQL和結果集不會被緩存?
面試官考點之什麼場景下會導致MySQL緩存失效?
面試官考點之查詢緩存是如何進行內存管理的?
面試官考點之MySQL是一次性分配所有的內存空間嗎?
面試官考點之緩存中的內存碎片無法避免,那麼有什麼辦法優化嗎?
面試官考點之MySQL4.0提出了查詢緩存,它設計出來是為了加速哪些查詢場景?
面試官考點之MySQL5.6中默認禁用,8.0以後完全移除,造成這個改變的原因是什麼?
面試官考點之生產環境要不要開啟MySQL緩存?
面試官考點之簡述一下什麼是查詢緩存機制?
MySQL服務器高負載情況下,我們需要採取一種措施給服務器減輕壓力,一個複雜的查詢是非常消耗性能的,
其中磁盤IO又佔據主要資源,緩存是對系統性能優化的一種重要手段。
查詢緩存機制設計是為了從根本上減少磁盤IO次數,MySQL開啟緩存後,將SQL和結果集以鍵值對KV的形式存儲在內存中。
當相同的SQL再次進入,MySQL識別是相同查詢喉,會直接返回緩存在內存中的結果集。
避免再次進行一系列複雜的解析優化和磁盤IO過程。
面試官考點之查詢如何命中緩存?
select id from user;
select id FROM user;
上面語句能命中緩存嗎?
MySQL緩存命中機制有嚴格苛刻的要求,在判斷命中前,MySQL不會對SQL做任何的解析處理。
SQL上的任何字符的不同,如大小寫、空格、注釋等都會導致緩存不命中
所以上面查詢時無法命中緩存的。
面試官考點之什麼場景下SQL和結果集不會被緩存?
或者說緩存規則是什麼?
第一種情況:查詢語句中包含不確定數據
例如查詢語句中包含不確定函數:NOW()、CURRENT_DATE()等。
因為每次執行這類帶了不確定數據的查詢所返回結果可能是不同的。
第二種情況:超過了query_cache_limit預設閾值
超出了緩存內存能承受的範圍,將放棄緩存!
面試官考點之什麼場景下會導致MySQL緩存失效?
任何對於表結構或者表數據的更新操作,一定會造成查詢緩存中的數據失效,同時查詢緩存值的相關條目也會被清空。
MySQL判定有更新操作,就會設置所有的查詢緩存失效。
面試官考點之查詢緩存是如何進行內存管理的?
MySQL服務啟動,緩存機制會在內存中開闢一塊內存,
其中會劃分出一塊區域
專用來管理維護緩存數據的元數據。
例如空間內存、數據表和查詢結果的映射,SQL和查詢結果的映射
MySQL緩存機制將剩餘的空閑空間分為一個個小數據塊,用來存儲緩存結果。
每個小塊中存儲自身的類型,大小和查詢結果數據,還有指向前後內存塊的指針
面試官考點之MySQL是一次性分配所有的內存空間嗎?
MySQL因為無法預知查詢結果大小,所以無法為每個查詢結果精確分配大小恰好匹配的緩存空間。
MySQL緩存機制採用的是邊查邊存,動態的去申請緩存內存。
一條SQL查詢緩存分配內存過程是怎麼樣的?
當有查詢結果需要緩存的時候,MySQL緩存機制會在SQL查詢開始(還未得到結果)時就去申請一塊內存空間(小數據塊),在不斷查詢中,如果發現不夠則繼續申請
,如果存儲完時有空餘則釋放多餘的內存空間
。
如果餘下的需要回收的空間很小,小於query_cache_min_res_unit,不能再次被使用,可能會造成內存碎片,影響查詢性能。
面試官考點之緩存中的內存碎片無法避免,那麼有什麼辦法優化嗎?
沒有什麼辦法能夠完全避免內存碎片,但是選擇合適的
query_cache_min_res_unit
可以減少由碎片導致的內存空間浪費。
值太小,則浪費的空間更少,但是會導致頻繁的內存塊申請操作
如果設置得太大,那麼碎片會很多
調整合適的值其實是在平衡內存浪費和CPU消耗
那麼我如何確定這個平衡值?
可以通過內存實際消耗,計算單個查詢的平均緩存大小
(query_cache_size - Qcache_free_memory)/ Qcache_queries_in_cahce
通過查看閑置內存塊數量(Qcahce_free_blocks)來觀察碎片。
如果產生的碎片過多,通過什麼方法可以整理碎片?
通過FLUSH_QUERY_CAHCE清理碎片
這個命令將所有的查詢緩存重新排序,
並將所有的空閑空間都聚焦到查詢緩存的一塊區域上。
面試官考點之MySQL4.0提出了查詢緩存,它設計出來是為了加速哪些查詢場景?
1、並發性和查詢QPS不高 2、被訪問的底層數據本質上是靜態或半靜態的 3、查詢密集型應用,更新頻率非常低而只讀查詢頻率非常高的場景
面試官考點之MySQL5.6中默認禁用,8.0以後完全移除,造成這個改變的原因是什麼?
理想情況下,上述查詢場景非常適合使用查詢緩存,但是實際的業務系統都是有CRUD操作
的。
在MySQL里QC是由一個全局鎖在控制,每次更新QC的內存塊都需要進行鎖定,數據更新頻繁,就會不斷的失效緩存操作,同時緩存失效會造成大量的查詢緩存碎片化
,還會導致服務器的負載升高,影響數據庫的穩定性。
所以MySQL官方經過抉擇,果斷移除了查詢緩存模塊。
面試官考點之生產環境要不要開啟MySQL緩存?
建議不開啟
根據MySQL官方的測試,如果對一個表執行簡單的查詢,
設置每次查詢都不一樣,
打開QC後,性能反而下降了13%左右
當然實際業務中,不會都是這種不同的請求,因此實際影響應該比這個小一些。
MySQL查詢緩存的目的是為了提升查詢性能,但它本身也是有性能開銷的。
需要在合適的業務場景下(讀寫壓力模型)
使用
不合適的業務場景不但不能提升查詢性能,查詢緩存反而會變成MySQL的瓶頸。
對寫密集型的應用場景來說,禁用緩存反而提高性能。
隨緣更新,整理不易,歡迎聯繫小白討論,大神巴巴請繞路!
更多精彩內容,歡迎關注微信公眾號:囧么肥事 (或搜索:jiongmefeishi)