溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

MySQL Query Cache講義

發(fā)布時(shí)間:2020-04-28 11:20:52 來源:億速云 閱讀:249 作者:三月 欄目:系統(tǒng)運(yùn)維

本文主要給大家介紹MySQL Query Cache講義,其所涉及的東西,從理論知識來獲悉,有很多書籍、文獻(xiàn)可供大家參考,從現(xiàn)實(shí)意義角度出發(fā),億速云累計(jì)多年的實(shí)踐經(jīng)驗(yàn)可分享給大家。

 一、前言

在當(dāng)今的各種系統(tǒng)中,緩存是對系統(tǒng)性能優(yōu)化的重要手段。MySQL Query Cache(MySQL查詢緩存)在MySQL Server中是默認(rèn)打開的,但是網(wǎng)上各種資料以及有經(jīng)驗(yàn)的DBA都建議生產(chǎn)環(huán)境中把MySQL Query Cache關(guān)閉。按道理,MySQL Server默認(rèn)打開,是鼓勵用戶使用緩存,但是大拿們卻建議關(guān)閉此功能,并且國內(nèi)各個云廠商提供的MySQL云服務(wù)中默認(rèn)都是關(guān)閉這個功能,這是為什么?他們在使用中遇到了什么坑?本文將會從以下幾方面來詳解MySQL Query Cache。

1.MySQL查詢緩存是什么?

MySQL緩存規(guī)則是什么?

如何配置和緩存MySQL緩存

MySQL緩存的優(yōu)缺點(diǎn)

生產(chǎn)要不要開啟MySQL緩存

MySQL Query Cache講義

二、 MySQL查詢緩存簡介
MySQL查詢緩存是MySQL中比較獨(dú)特的一個緩存區(qū)域,用來緩存特定Query的整個結(jié)果集信息,且共享給所有客戶端。為了提高完全相同的Query語句的響應(yīng)速度,MySQL Server會對查詢語句進(jìn)行Hash計(jì)算后,把得到的hash值與Query查詢的結(jié)果集對應(yīng)存放在Query Cache中。當(dāng)MySQL Server打開Query Cache之后,MySQL Server會對接收到的每一個SELECT 語句通過特定的Hash算法計(jì)算該Query的Hash值,然后通過該hashi值到Query Cache中去匹配。

如果沒有匹配,將這個hash值存放在一個hash鏈表中,并將Query的結(jié)果集存放到cache中,存放hashi值鏈表的每個hash節(jié)點(diǎn)存放了相應(yīng)Quey結(jié)果集在cache中的地址,以及該query所涉及到一些table相關(guān)信息;
如果通過hash值匹配到了一樣的Query,則直接將cache中相應(yīng)的Query結(jié)果集返回給客戶端。
目前MySQL Query Cache只會cache select語句,其他類似show ,use的語句不會被cache MySQL 的每個Query Cache都是以SQL文本作為key來存儲的,在應(yīng)用Query Cache之前,SQL文本不會做任何處理。也就是說,兩個SQL語句,只要相差哪怕一個字符(例如大小寫不一樣,多一個空格,多注釋),那么這兩個SQL將使用不同的Cache地址。如: 下面三條SQL將會被存儲在三個不同的緩存里,雖然他們的結(jié)果都是一樣的。select FROM people where name='surfchen'; select FROM people where /hey~/ name='surfchen'; SELECT * FROM people where name='surfchen';
三、MySQL緩存機(jī)制
MySQL緩存機(jī)制簡單的說就是緩存sql文本及查詢結(jié)果,如果運(yùn)行相同的SQL,云服務(wù)器直接從緩存中取到結(jié)果,而不需要再去解析和執(zhí)行SQL。如果表更改了,那么使用這個表的所有緩存查詢將不再有效,查詢緩存中值相關(guān)條目被清空。這里的更改指的是表中任何數(shù)據(jù)或是結(jié)構(gòu)發(fā)生改變,包括INSERT、UPDATE、 DELETE、TRUNCATE、ALTER TABLE、DROP TABLE或DROP DATABASE等,也包括那些映射到改變了的表使用MERGE表的查詢。顯然,這對于頻繁更新的表,查詢緩存是不適合的,而對于一些不常改變數(shù)據(jù)且有大量相同SQL查詢的表,查詢緩存會節(jié)約很大的性能。

查詢必須是完全相同(逐字節(jié)相同)才能夠被認(rèn)為是相同的。另外,同樣的查詢字符串由于其它原因可能認(rèn)為是不同的。使用不同的數(shù)據(jù)庫、不同的協(xié)議版本或者不同 默認(rèn)字符集的查詢被認(rèn)為是不同的查詢并且分別進(jìn)行緩存。

需要注意的是MySQL Query Cache 是對大小寫敏感的,因?yàn)镼uery Cache 在內(nèi)存中是以 HASH 結(jié)構(gòu)來進(jìn)行映射,HASH 算法基礎(chǔ)就是組成 SQL 語句的字符,所以 任何SQL語句的改變重新cache.

3.1 緩存規(guī)則

開啟了緩存,MySQL Server會自動將查詢語句和結(jié)果集返回到內(nèi)存,下次再查直接從內(nèi)存中??;
緩存的結(jié)果是通過sessions共享的,所以一個client查詢的緩存結(jié)果,另一個client也可以使用
MySQL Query Cache內(nèi)容為 select 的結(jié)果集, cache 使用完整的SQL字符串做 key, 并區(qū)分大小寫,空格等。即兩個SQL必須完全一致才會導(dǎo)致cache命中。即檢查查詢緩存時(shí),MySQL Server不會對SQL做任何處理,它精確的使用客戶端傳來的查詢,只要字符大小寫或注釋有點(diǎn)不同,查詢緩存就認(rèn)為是不同的查詢;
prepared statement永遠(yuǎn)不會cache到結(jié)果,即使參數(shù)完全一樣。在 5.1 之后會得到改善。
where條件中如包含任何一個不確定的函數(shù)將永遠(yuǎn)不會被cache, 比如current_date, now等。
date 之類的函數(shù)如果返回是以小時(shí)或天級別的,最好先算出來再傳進(jìn)去。
select from foo where date1=current_date -- 不會被 cache
select
from foo where date1='2008-12-30' -- 被cache, 正確的做法
太大的result set不會被cache (< query_cache_limit)
MySQL緩存在分庫分表環(huán)境下是不起作用的
執(zhí)行SQL里有觸發(fā)器,自定義函數(shù)時(shí),MySQL緩存也是不起作用的

3.2 緩存失效

在表的結(jié)構(gòu)或數(shù)據(jù)發(fā)生改變時(shí),查詢緩存中的數(shù)據(jù)不再有效。如INSERT、UPDATE、 DELETE、TRUNCATE、ALTER TABLE、DROP TABLE或DROP DATABASE會導(dǎo)致緩存數(shù)據(jù)失效。所以查詢緩存適合有大量相同查詢的應(yīng)用,不適合有大量數(shù)據(jù)更新的應(yīng)用。
一旦表數(shù)據(jù)進(jìn)行任何一行的修改,基于該表相關(guān)cache立即全部失效。

3.3 手動清理緩存手動清理緩存可以使用下面三個SQL

FLUSH QUERY CACHE; #清理查詢緩存內(nèi)存碎片
RESET QUERY CACHE;#從查詢緩存中移除所有查詢
FLUSH TABLES; #關(guān)閉所有打開的表,同時(shí)該操作會清空查詢緩存中的內(nèi)容

3.4 緩存機(jī)制中的內(nèi)存管理

MySQL Query Cache 使用內(nèi)存池技術(shù),自己管理內(nèi)存釋放和分配,而不是通過操作系統(tǒng)。內(nèi)存池使用的基本單位是變長的block, 用來存儲類型、大小、數(shù)據(jù)等信息;一個result set的cache通過鏈表把這些block串起來。block最短長度為query_cache_min_res_unit。

當(dāng)服務(wù)器啟動的時(shí)候,會初始化緩存需要的內(nèi)存,是一個完整的空閑塊。當(dāng)查詢結(jié)果需要緩存的時(shí)候,先從空閑塊中申請一個數(shù)據(jù)塊為參數(shù)query_cache_min_res_unit配置的空間,即使緩存數(shù)據(jù)很小,申請數(shù)據(jù)塊也是這個,因?yàn)椴樵冮_始返回結(jié)果的時(shí)候就分配空間,此時(shí)無法預(yù)知結(jié)果多大。

分配內(nèi)存塊需要先鎖住空間塊,所以操作很慢,MySQL會盡量避免這個操作,選擇盡可能小的內(nèi)存塊,如果不夠,繼續(xù)申請,如果存儲完時(shí)有空余則釋放多余的。

但是如果并發(fā)的操作,余下的需要回收的空間很小,小于query_cache_min_res_unit,不能再次被使用,就會產(chǎn)生碎片。如圖:

四、MySQL緩存發(fā)揮作用的情況
1、查詢緩存可以降低查詢執(zhí)行的時(shí)間,但是卻不能減少查詢結(jié)果傳輸?shù)木W(wǎng)絡(luò)消耗,如果網(wǎng)絡(luò)傳輸消耗是整個查詢過程的主要瓶頸,那么查詢緩存的作用也很小。

2、對于那些需要消耗大量資源的查詢通常都是非常適合緩存的,對于復(fù)雜的SELECT語句都可以使用查詢緩存,不過需要注意的是,涉及表上的UPDATE、DELETE、INSERT操作相比SELECT來說要非常少才行。

3、查詢緩存命中率:Qcache_hits/(Qcahce_hits+Com_select),查詢緩存命中率多大才是好的命中率,需要具體情況具體分析。只要查詢緩存帶來的效率提升大于查詢緩存帶來的額外消耗,即使30%的命中率也是值得。另外,緩存了哪些查詢也很重要,如果被緩存的查詢本身消耗巨大,那么即使緩存命中率低,對系統(tǒng)性能提升仍然是有好處的。

4、任何SELECT語句沒有從查詢緩存中返回都稱為“緩存未命中”,以如下列情況:

查詢語句無法被緩存,可能因?yàn)椴樵冎邪粋€不確定的函數(shù),或者查詢結(jié)果太大而無法緩存。
MySQL從未處理這個查詢,所以結(jié)果也從不曾被緩存過。
雖然之前緩存了查詢結(jié)果,但由于查詢緩存的內(nèi)存用完了,MYSQL需要刪除某些緩存,或者由于數(shù)據(jù)表被修改導(dǎo)致緩存失效。
如果服務(wù)器上有大量緩存緩存未命中,但是實(shí)際上絕大查詢都被緩存了,那么一定是有如下情況發(fā)生:

查詢緩存還沒有完成預(yù)熱,即MySQL還沒有機(jī)會將查詢結(jié)果都緩存起來。
查詢語句之前從未執(zhí)行過。如果應(yīng)用程序不會重復(fù)執(zhí)行一條查詢語句,那么即使完成預(yù)熱仍然會有很多緩存未命中。
緩存失效操作太多,緩存碎片、內(nèi)存不足、數(shù)據(jù)修改都會造成緩存失效??梢酝ㄟ^參數(shù)Com_*來查看數(shù)據(jù)修改的情況(包括Com_update,Com_delete等),還可以通過Qcache_lowmem_prunes來查看有多少次失效是由于內(nèi)存不足導(dǎo)致的。
5、有一個直觀的方法能夠反映查詢緩存是否對系統(tǒng)有好處,推薦一個指標(biāo):”命中和寫入“的比率,即Qcache_hits和Qcache_inserts的比值。根據(jù)經(jīng)驗(yàn)來看,當(dāng)這個比值大于3:1時(shí)通常查詢緩存是有效的,如果能達(dá)到10:1最好。

6、通??梢酝ㄟ^觀察查詢緩存內(nèi)存的實(shí)際使用情況Qcache_free_memory,來確定是否需要縮小或者擴(kuò)大查詢緩存。

五、MySQL緩存管理和配置
5.1 MySQL緩存相關(guān)的配置參數(shù)

mysql> show variables like '%query_cache%';
+------------------------------+---------+
| Variable_name | Value |
+------------------------------+---------+
| have_query_cache | YES | --查詢緩存是否可用
| query_cache_limit | 1048576 | --可緩存具體查詢結(jié)果的最大值
| query_cache_min_res_unit | 4096 | --查詢緩存分配的最小塊的大小(字節(jié))
| query_cache_size | 599040 | --查詢緩存的大小
| query_cache_type | ON | --是否支持查詢緩存
| query_cache_wlock_invalidate | OFF | --控制當(dāng)有寫鎖加在表上的時(shí)候,是否先讓該表相關(guān)的 Query Cache失效
+------------------------------+---------+
6 rows in set (0.02 sec)
have_query_cache
該MySQL Server是否支持Query Cache。

query_cache_limit
MySQL能夠緩存的最大查詢結(jié)果,查詢結(jié)果大于該值時(shí)不會被緩存。默認(rèn)值是1048576(1MB)如果某個查詢的結(jié)果超出了這個值,Qcache_not_cached的值會加1,如果某個操作總是超出,可以考慮在SQL中加上SQL_NO_CACHE來避免額外的消耗。

query_cache_min_res_unit
查詢緩存分配的最小塊的大小(字節(jié))。 默認(rèn)值是4096(4KB)。當(dāng)查詢進(jìn)行的時(shí)候,MySQL把查詢結(jié)果保存在qurey cache中,但如果要保存的結(jié)果比較大,超過query_cache_min_res_unit的值 ,這時(shí)候mysql將一邊檢索結(jié)果,一邊進(jìn)行保存結(jié)果,所以,有時(shí)候并不是把所有結(jié)果全部得到后再進(jìn)行一次性保存,而是每次分配一塊query_cache_min_res_unit大小的內(nèi)存空間保存結(jié)果集,使用完后,接著再分配一個這樣的塊,如果還不不夠,接著再分配一個塊,依此類推,也就是說,有可能在一次查詢中,mysql要進(jìn)行多次內(nèi)存分配的操作。適當(dāng)?shù)恼{(diào)節(jié)query_cache_min_res_unit可以優(yōu)化內(nèi)存如果你的查詢結(jié)果都是一些small result,默認(rèn)的query_cache_min_res_unit可能會造成大量的內(nèi)存碎片如果你的查詢結(jié)果都是一些larger resule,你可以適當(dāng)?shù)陌裶uery_cache_min_res_unit調(diào)大

query_cache_size
為緩存查詢結(jié)果分配的內(nèi)存的數(shù)量,單位是字節(jié),且數(shù)值必須是1024的整數(shù)倍。默認(rèn)值是0,即禁用查詢緩存。請注意如果設(shè)置了該值,即使query_cache_type設(shè)置為0也將分配此數(shù)量的內(nèi)存。

query_cache_type
設(shè)置查詢緩存類型,默認(rèn)為ON。設(shè)置GLOBAL值可以設(shè)置后面的所有客戶端連接的類型??蛻舳丝梢栽O(shè)置SESSION值以影響他們自己對查詢緩存的使用。下面的表顯示了可能的值:

query_cache_wlock_invalidate
如果某個表被鎖住,是否返回緩存中的數(shù)據(jù),默認(rèn)關(guān)閉,也是建議的。一般情況,當(dāng)客戶端對MyISAM表進(jìn)行WRITE鎖定時(shí),如果查詢結(jié)果位于查詢緩存中,則其它客戶端未被鎖定,可以對該表進(jìn)行查詢。將該變量設(shè)置為1,則可以對表進(jìn)行WRITE鎖定,使查詢緩存內(nèi)所有對該表進(jìn)行的查詢變得非法。這樣當(dāng)鎖定生效時(shí),可以強(qiáng)制其它試圖訪問表的客戶端來等待。

5.2 開啟關(guān)閉緩存

開啟緩存
mysql> set global query_cache_size = 600000; --設(shè)置緩存內(nèi)存大小
mysql> set global query_cache_type = ON; --開啟查詢緩存
關(guān)閉緩存
mysql> set global query_cache_size = 0; --設(shè)置緩存內(nèi)存大小為0, 即初始化是不分配緩存內(nèi)存
mysql> set global query_cache_type = OFF; --關(guān)閉查詢緩存
set global時(shí)需要有SUPER權(quán)限
六、MySQL Query Cache對性能的影響
6.1 MySQL Query Cache的額外開銷

如上圖所示: 在MySQL Server中打開Query Cache對數(shù)據(jù)庫的讀和寫都會帶來額外的消耗:

1) 讀查詢開始之前必須檢查是否命中緩存。
2) 如果讀查詢可以緩存,那么執(zhí)行完查詢操作后,會查詢結(jié)果和查詢語句寫入緩存。
3) 當(dāng)向某個表寫入數(shù)據(jù)的時(shí)候,必須將這個表所有的緩存設(shè)置為失效,如果緩存空間很大,則消耗也會很大,可能使系統(tǒng)僵死一段時(shí)間,因?yàn)檫@個操作是靠全局鎖操作來保護(hù)的。
4) 對InnoDB表,當(dāng)修改一個表時(shí),設(shè)置了緩存失效,但是多版本特性會暫時(shí)將這修改對其他事務(wù)屏蔽,在這個事務(wù)提交之前,所有查詢都無法使用緩存,直到這個事務(wù)被提交,所以長時(shí)間的事務(wù),會大大降低查詢緩存的命中
6.2 MySQL Query Cache碎片優(yōu)化

如上圖所示, 沒有什么辦法能夠完全避免碎片,但是選擇合適的query_cache_min_res_unit可以幫你減少由碎片導(dǎo)致的內(nèi)存空間浪費(fèi)。這個值太小,則浪費(fèi)的空間更少,但是會導(dǎo)致頻繁的內(nèi)存塊申請操作;如果設(shè)置得太大,那么碎片會很多。調(diào)整合適的值其實(shí)是在平衡內(nèi)存浪費(fèi)和CPU消耗。可以通過內(nèi)存實(shí)際消耗(query_cache_size - Qcache_free_memory)除以Qcache_queries_in_cahce計(jì)算單個查詢的平均緩存大小??梢酝ㄟ^Qcahce_free_blocks來觀察碎片。

通過FLUSH_QUERY_CAHCE完成碎片整理,這個命令將所有的查詢緩存重新排序,并將所有的空閑空間都聚焦到查詢緩存的一塊區(qū)域上。

6.3 MySQL緩存狀態(tài)查看

mysql> SHOW STATUS LIKE 'Qcache%';
+-------------------------+--------+
| Variable_name | Value |
+-------------------------+--------+
| Qcache_free_blocks | 1 | ----在查詢緩存中的閑置塊,如果該值比較大,則說明Query Cache中的內(nèi)存碎片可能比較多。FLUSH QUERY CACHE會對緩存中的碎片進(jìn)行整理,從而得到一個較大的空閑內(nèi)存塊。
| Qcache_free_memory | 382704 | ----剩余緩存的大小
| Qcache_hits | 198 | ----緩存命中次數(shù)
| Qcache_inserts | 131 | ----緩存被插入的次數(shù),也就是查詢沒有命中的次數(shù)。
| Qcache_lowmem_prunes | 0 | ----由于內(nèi)存低而被刪除掉的緩存條數(shù),如果這個數(shù)值在不斷增長,那么一般是Query Cache的空閑內(nèi)存不足(通過Qcache_free_memory判斷),或者內(nèi)存碎片較嚴(yán)重(通過Qcache_free_blocks判斷)。
| Qcache_not_cached | 169 | ----沒有被緩存的條數(shù),有三種情況會導(dǎo)致查詢結(jié)果不會被緩存:其一,由于query_cache_type的設(shè)置;其二,查詢不是SELECT語句;其三,使用了now()之類的函數(shù),導(dǎo)致查詢語句一直在變化。
| Qcache_queries_in_cache | 128 | ----緩存中有多少條查詢語句
| Qcache_total_blocks | 281 | ----總塊數(shù)
+-------------------------+--------+
8 rows in set (0.00 sec)
6.4 Query Cache碎片率Query Cache碎片率 = Qcache_free_blocks / Qcache_total_blocks * 100%

如果Query Cache碎片率超過20%,則可以用FLUSH QUERY CACHE整理內(nèi)存碎片;如果你的查詢都是小數(shù)據(jù)量的話,可以嘗試減小query_cache_min_res_unit。

6.5 Query Cache利用率Query Cache利用率 = (query_cache_size - Qcache_free_memory) / query_cache_size * 100%

Query Cache利用率在25%以下的話,說明query_cache_size設(shè)置的過大,可適當(dāng)減??;Query Cache利用率在80%以上,而且Qcache_lowmem_prunes > 50的話,說明query_cache_size可能有點(diǎn)小,或者就是內(nèi)存碎片太多。

6.6 Query Cache命中率

可緩存查詢的Query Cache命中率 = Qcache_hits / (Qcache_hits + Qcache_inserts) 100%
涵蓋所有查詢的Query Cache命中率 = Qcache_hits / (Qcache_hits + Com_select)
100%
若命中率在50-70%的范圍之內(nèi),則表明Query Cache的緩存效率較高。如果命中率明顯小于50%,那么建議禁用(將query_cache_type設(shè)置為0(OFF))或按需使用(將query_cache_type設(shè)置為2(DEMAND))Query Cache,節(jié)省的內(nèi)存可以用作InnoDB的緩沖池。

6.7 如何判斷Query Cache是空閑內(nèi)存不足,還是內(nèi)存碎片太多?如果Qcache_lowmem_prunes值比較大,表示Query Cache的內(nèi)存空間大小設(shè)置太小,需要增大。

如果Qcache_free_blocks值比較大,表示內(nèi)存碎片較多,需要使用FLUSH QUERY CACHE語句清理內(nèi)存碎片。

6.8 系統(tǒng)變量query_cache_min_res_unit應(yīng)當(dāng)設(shè)置為多大?query_cache_min_res_unit的計(jì)算公式如下所示:

query_cache_min_res_unit = (query_cache_size - Qcache_free_memory) / Qcache_queries_in_cache

其中,一般不建議將Query Cache的大?。ㄒ簿褪莙uery_cache_size系統(tǒng)變量)設(shè)置超過256MB。

七、MySQL Query Cache優(yōu)缺點(diǎn)
7.1. 優(yōu)點(diǎn)Query Cache的查詢,發(fā)生在MySQL接收到客戶端的查詢請求、查詢權(quán)限驗(yàn)證之后和查詢SQL解析之前。也就是說,當(dāng)MySQL接收到客戶端的查詢SQL之后,僅僅只需要對其進(jìn)行相應(yīng)的權(quán)限驗(yàn)證之后,就會通過Query Cache來查找結(jié)果,甚至都不需要經(jīng)過Optimizer模塊進(jìn)行執(zhí)行計(jì)劃的分析優(yōu)化,更不需要發(fā)生任何存儲引擎的交互。由于Query Cache是基于內(nèi)存的,直接從內(nèi)存中返回相應(yīng)的查詢結(jié)果,因此減少了大量的磁盤I/O和CPU計(jì)算,導(dǎo)致效率非常高。

7.2. 缺點(diǎn)Query Cache的優(yōu)點(diǎn)很明顯,但是也不能忽略它所帶來的一些缺點(diǎn):

查詢語句的hash計(jì)算和hash查找?guī)淼馁Y源消耗。如果將query_cache_type設(shè)置為1(也就是ON),那么MySQL會對每條接收到的SELECT類型的查詢進(jìn)行hash計(jì)算,然后查找這個查詢的緩存結(jié)果是否存在。雖然hash計(jì)算和查找的效率已經(jīng)足夠高了,一條查詢語句所帶來的開銷可以忽略,但一旦涉及到高并發(fā),有成千上萬條查詢語句時(shí),hash計(jì)算和查找所帶來的開銷就必須重視了。
Query Cache的失效問題。如果表的變更比較頻繁,則會造成Query Cache的失效率非常高。表的變更不僅僅指表中的數(shù)據(jù)發(fā)生變化,還包括表結(jié)構(gòu)或者索引的任何變化。
查詢語句不同,但查詢結(jié)果相同的查詢都會被緩存,這樣便會造成內(nèi)存資源的過度消耗。查詢語句的字符大小寫、空格或者注釋的不同,Query Cache都會認(rèn)為是不同的查詢(因?yàn)樗麄兊膆ash值會不同)。
相關(guān)系統(tǒng)變量設(shè)置不合理會造成大量的內(nèi)存碎片,這樣便會導(dǎo)致Query Cache頻繁清理內(nèi)存。
八、 生產(chǎn)如何設(shè)置MySQL Query Cache

MySQL中的Query Cache是一個適用較少情況的緩存機(jī)制。如上圖所示,如果緩存命中率非常高的話,有測試表明在極端情況下可以提高效率238%。但實(shí)際情況如何?Query Cache有如下規(guī)則,如果數(shù)據(jù)表被更改,那么和這個數(shù)據(jù)表相關(guān)的全部Cache全部都會無效,并刪除之。這里“數(shù)據(jù)表更改”包括: INSERT, UPDATE, DELETE, TRUNCATE, ALTER TABLE, DROP TABLE, or DROP DATABASE等。舉個例子,如果數(shù)據(jù)表posts訪問頻繁,那么意味著它的很多數(shù)據(jù)會被QC緩存起來,但是每一次posts數(shù)據(jù)表的更新,無論更新是不是影響到了cache的數(shù)據(jù),都會將全部和posts表相關(guān)的cache清除。如果你的數(shù)據(jù)表更新頻繁的話,那么Query Cache將會成為系統(tǒng)的負(fù)擔(dān)。有實(shí)驗(yàn)表明,糟糕時(shí),QC會降低系統(tǒng)13%的處理能力。

如果你的應(yīng)用對數(shù)據(jù)庫的更新很少,那么QC將會作用顯著。比較典型的如博客系統(tǒng),一般博客更新相對較慢,數(shù)據(jù)表相對穩(wěn)定不變,這時(shí)候QC的作用會比較明顯。

但是一個更新頻繁的BBS系統(tǒng)。下面是一個實(shí)際運(yùn)行的論壇數(shù)據(jù)庫的狀態(tài)參數(shù):QCache_hit 5280438QCache_insert 8008948Qcache_not_cache 95372Com select 8104159可以看到,數(shù)據(jù)庫一共往Query Cache中寫入了約800W次緩存,但是實(shí)際命中的只有約500W次。也就是說,每一個緩存的使用率約為0.66次。很難說,該緩存的作用是否大于Query Cache系統(tǒng)所帶來的開銷。但是有一點(diǎn)是很肯定的,Query Cache緩存的作用是很微小的,如果應(yīng)用層能夠?qū)崿F(xiàn)緩存,將可以忽略Query Cache的效果。

所以,如果經(jīng)常有更新的系統(tǒng),想要獲得較高tps的話,建議一開始就關(guān)閉Query Cache

九、 查詢緩存的替代方案MySQL查詢緩存工作的原則是:執(zhí)行查詢最快的方式就是不去執(zhí)行,但是查詢?nèi)匀恍枰l(fā)送到服務(wù)器端,服務(wù)器也還需要做一點(diǎn)點(diǎn)工作,如果對于某些查詢完全不需要與服務(wù)器通信效果會如何呢,這時(shí)客戶端緩存可以很大程度上分擔(dān)MySQL服務(wù)器的壓力。

看了以上MySQL Query Cache講義介紹,希望能給大家在實(shí)際運(yùn)用中帶來一定的幫助。本文由于篇幅有限,難免會有不足和需要補(bǔ)充的地方,大家可以繼續(xù)關(guān)注億速云行業(yè)資訊板塊,會定期給大家更新行業(yè)新聞和知識,如有需要更加專業(yè)的解答,可在官網(wǎng)聯(lián)系我們的24小時(shí)售前售后,隨時(shí)幫您解答問題的。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI