App下載

對(duì)于在MySQL中查詢緩存的基礎(chǔ)知識(shí)分享!案例干貨分享!

孫尚香 2021-09-26 14:46:27 瀏覽數(shù) (2612)
反饋

MySQL 緩存技術(shù)徽標(biāo)。

查詢?cè)诿總€(gè) MySQL 數(shù)據(jù)庫(kù)管理員甚至精通數(shù)據(jù)庫(kù)的開發(fā)人員的生活中無(wú)處不在。正如我們?cè)谥暗囊恍┎┛臀恼轮幸呀?jīng)指出的那樣,查詢只是由較小任務(wù)組成的任務(wù)。為了優(yōu)化它們的性能,我們應(yīng)該讓那些較小的任務(wù)執(zhí)行得更快或者根本不執(zhí)行。首先,我們必須檢查 MySQL 如何執(zhí)行查詢。

什么是查詢緩存?

MySQL 查詢緩存雖然在 MySQL 5.7 中被棄用(并在 8.0 中刪除),但存儲(chǔ)以前在內(nèi)存中運(yùn)行的語(yǔ)句:換句話說(shuō),查詢緩存通常將SELECT語(yǔ)句存儲(chǔ)在數(shù)據(jù)庫(kù)的內(nèi)存中。因此,如果我們運(yùn)行一個(gè)查詢,然后在一段時(shí)間后再次運(yùn)行完全相同的查詢,結(jié)果將更快地返回,因?yàn)樗鼈儗膬?nèi)存而不是從磁盤中檢索。

查詢緩存緩存查詢和結(jié)果集。因此,當(dāng)我們運(yùn)行相同的查詢時(shí),查詢緩存的結(jié)果會(huì)立即返回。查詢緩存大小可以通過(guò)設(shè)置query_cache_size系統(tǒng)變量來(lái)控制,但這里有一個(gè)警告:如果您希望查詢使用查詢緩存,它們必須,必須,必須相同,逐字節(jié)。這意味著即使您認(rèn)為這兩個(gè)查詢應(yīng)該以完全相同的方式緩存:

SELECT * FROM demo_table WHERE column = 'Demo'; 
select * from demo_table where column = 'Demo';

事實(shí)上,他們不是。它們不是因?yàn)?MySQL 查詢緩存要求其所有查詢都相同,并且即使它們相差一個(gè)字節(jié)也不會(huì)返回任何結(jié)果。

所以,總結(jié)一下,當(dāng) MySQL 執(zhí)行語(yǔ)句時(shí),它做的第一件事就是檢查是否啟用了查詢緩存(如果需要復(fù)習(xí),請(qǐng)回到我們上一篇關(guān)于慢速 MySQL 查詢的博客文章。)如果查詢緩存啟用后,MySQL 將首先檢查與該查詢的任何相關(guān)匹配項(xiàng);如果沒(méi)有匹配項(xiàng),MySQL 將繼續(xù)下一步。但是,如果存在相同的匹配項(xiàng),MySQL 將從其查詢緩存中返回結(jié)果。

MySQL內(nèi)部的查詢緩存

在此之前返回比賽,MySQL的查詢緩存要求MySQL的確認(rèn):d OES該用戶有必要的權(quán)限才能完成這樣的動(dòng)作?我應(yīng)該拒絕執(zhí)行查詢嗎?

以下是 MySQL 檢查的權(quán)限列表:

特權(quán)

簡(jiǎn)要說(shuō)明
ALL賦予特定 MySQL 用戶所有權(quán)限。
SELECT授予特定 MySQL 用戶從指定數(shù)據(jù)庫(kù)中選擇行的權(quán)限。
UPDATE授予特定 MySQL 用戶更新指定表中現(xiàn)有行的權(quán)限。
SHOW DATABASES使特定 MySQL 用戶能夠獲取存在于一個(gè)特定 MySQL 實(shí)例中的所有 MySQL 數(shù)據(jù)庫(kù)的列表。
USAGE賦予用戶僅使用 MySQL 的權(quán)力,這意味著用戶不能在其中運(yùn)行任何查詢。本質(zhì)上是無(wú)特權(quán)的同義詞。


有更多的特權(quán),但你明白了。權(quán)限對(duì)于查詢緩存很重要,因?yàn)?MySQL 還將與表相關(guān)的信息與緩存查詢一起存儲(chǔ)。權(quán)限也很重要,因?yàn)樗?MySQL 結(jié)果檢查過(guò)程的第一階段之一。這是一切的工作原理:

優(yōu)先識(shí)別

MYSQL 狀態(tài)

解釋
1MySQL 正在檢查查詢緩存中的權(quán)限。首先,MySQL 檢查特定用戶是否有權(quán)訪問(wèn)特定結(jié)果。
2MySQL 正在檢查查詢本身的查詢緩存。接下來(lái),MySQL 開始檢查查詢緩存中是否存在相同的查詢。如果匹配,MySQL 返回;如果沒(méi)有,MySQL 繼續(xù)下一步。
3MySQL 將查詢緩存中的條目標(biāo)記為無(wú)效。隨著表的變化,查詢緩存需要更新。所以在這一步中,MySQL 決定將查詢緩存中的條目標(biāo)記為無(wú)效。
4發(fā)送結(jié)果。MySQL 發(fā)送緩存的結(jié)果并顯示它。
5將結(jié)果存儲(chǔ)在緩存中。MySQL 將查詢結(jié)果保存在查詢緩存中。
6查詢緩存被鎖定。緩存過(guò)程現(xiàn)在結(jié)束——MySQL 鎖定查詢緩存。

“MySql沒(méi)有緩存!”:要看查詢緩存是否損壞?

當(dāng)使用函數(shù)或分區(qū)時(shí),如果我們?cè)诓樵冎惺褂萌魏巫兞?,查詢緩存也將無(wú)效。例如,如果我們正在處理大數(shù)據(jù),并且我們使用SELECT ... INTO OUTFILE將大數(shù)據(jù)集加載到 MySQL 中,則結(jié)果同樣不會(huì)被緩存。通常,查詢緩存SELECT ... [LOCK | FOR | INTO]在使用類似查詢時(shí)不起作用,如果我們正在檢查具有NULL值的列中的AUTO_INCREMENT值,則查詢緩存也無(wú)法使用,這意味著如果我們有一個(gè)increment帶有 的列AUTO_INCREMENT,并且我們運(yùn)行這樣的查詢所以:

SELECT * FROM demo_table WHERE increment IS NULL;

查詢緩存也不會(huì)生效。

所有這些功能可能會(huì)讓你們中的一些人大喊“它不起作用!” - 你是對(duì)的。查詢緩存并不總是有效:與 MySQL 中的所有內(nèi)容一樣,它也有局限性。除了上述那些,當(dāng)語(yǔ)句生成警告或語(yǔ)句在帶有TEMPORARY存儲(chǔ)引擎的表上運(yùn)行時(shí)以及在其他一些極端情況下,它拒絕工作。每次有人向表寫入任何內(nèi)容時(shí),查詢緩存也會(huì)清空。

查詢緩存的功能也取決于query_cache_size參數(shù)。此參數(shù)越大越好,但請(qǐng)注意,此參數(shù)在很大程度上取決于您的內(nèi)存。請(qǐng)記住,查詢緩存的基本結(jié)構(gòu)默認(rèn)至少需要 40kB 的存儲(chǔ)空間,其默認(rèn)值可能在 1MB 到 16MB 之間。但是,如果您的數(shù)據(jù)庫(kù)非常忙于讀取數(shù)據(jù),則更大的值可能有助于找到最佳解決方案,您必須再次進(jìn)行試驗(yàn)。

您還可以通過(guò)運(yùn)行該RESET QUERY CACHE語(yǔ)句來(lái)刪除查詢緩存中的所有內(nèi)容。如果您使用類似 的語(yǔ)句FLUSH TABLES,所有值也將從查詢緩存中刪除。

MySQL 甚至允許您通過(guò)運(yùn)行查詢來(lái)查看查詢緩存中存儲(chǔ)了多少查詢:

SHOW STATUS LIKE 'Qcache_queries_in_cache%';

您會(huì)得到如下所示的結(jié)果:

MySQL:

+-------------------------+--------+
| Variable_name           | Value  |
+-------------------------+--------+
| Qcache_queries_in_cache | 1      |
+-------------------------+--------+

在這種情況下,我們可以看到我們的查詢緩存當(dāng)前緩存了一個(gè)結(jié)果。執(zhí)行類似的語(yǔ)句FLUSH TABLES,所有值都將消失。

總結(jié)

在 MySQL 中,查詢緩存是一個(gè)非常強(qiáng)大的野獸。它通常能夠存儲(chǔ)各種各樣的值并從內(nèi)存中返回它們,而不是從磁盤中返回它們,以加快查詢執(zhí)行時(shí)間。然而,它并非沒(méi)有缺陷。查詢緩存有一些限制,但如果您知道自己在做什么,應(yīng)該沒(méi)問(wèn)題。

查詢緩存對(duì)于SELECT查詢最有用的。


0 人點(diǎn)贊