衆所周知,系統讀取數據時,從內存中讀取要比從硬盤上速度要快好幾百倍。故如今絕大部分應用系統,都會最大程度的使用緩存(內存中的一個存儲區域),來提升系統的運行效率。MySQL數據庫也不例外。在這裏,筆者將結合本身的工做經驗,跟你們探討一下,MySQL數據庫中緩存的管理技巧:如何合理配置MySQL數據庫緩存,提升緩存命中率。數據庫
1、何時應用系統會從緩存中獲取數據?緩存
數據庫從服務器上讀取數據時,能夠從硬盤的數據文件中獲取數據,也能夠從數據庫緩存中讀取數據。如今數據庫管理員須要搞清楚的是,在什麼樣的狀況下,系統是從緩存中讀取數據,而不是從硬盤的數據文件中讀取數據?服務器
簡單的說,數據緩存就是內存中的一塊存儲區域,其存儲了用戶的SQL文本以及相關的查詢結果。一般狀況下,用戶下次查詢時,若是所使用的SQL文本是相同的,而且自從上次查詢後,相關的紀錄沒有被更新過,此時數據庫就直接採用緩存中的內容。從這個原則中,能夠看到若是要直接使用緩存中的數據,至少要知足如下幾個條件。併發
一是所採用的SQL文本是相同的。當先後兩次用戶使用了相同的SQL語句(假設不考慮其餘條件),則服務器會從緩存中讀取結果,而不須要再去解析和執行SQL語句。這裏須要注意的是,這裏的SQL文本必須一次不差的徹底相同。若是先後兩次查詢,使用了不一樣的查詢條件。如第一次查詢時沒有輸入Where條件語句。後來發現數據量過多,利用了Where條件了過濾查詢的結果。此時即便最後的查詢結果是相同的,系統仍然是從數據文件中獲取數據,而不是從數據緩存中。再如,Select後面所使用的字段名稱也必須是相同的。若是有一個字段名稱不一樣或者先後兩次查詢所使用的字段數量不一樣,則系統都會認爲是不一樣的SQL語句,而從新解析並查詢。工具
二是從數據緩存的角度考慮,大小寫是不敏感的。如先後兩次查詢時,採用的字段名稱可能只有大小寫的差別。如第一次使用的是大小,第二次使用的是小寫,這系統認爲仍然是相同的SQL語句。或者說關鍵字大小寫等等這都是不敏感的。性能
三是要知足二次查詢之間,數據記錄包括表結構都沒有被更改過。若是記錄所在的標更改了,如增長了一個字段等等,此時使用這個表的全部緩衝數據系統將自動清空。這裏須要注意,這裏指的更改是一個廣義的更改,包括表中任何數據或者結果的改變。舉一個簡單的例子,第一次查詢時用戶須要查詢2010年的出貨數據。查詢後有用戶在這個表中插入了一條2011年1月份的出貨信息。而後又有用戶須要查詢2010年的出貨信息。使用的SQL語句與第一次查詢時徹底相同。在這種狀況下,數據庫系統會使用緩存中的數據嗎?答案是否認的。由於當中間用戶插入一條記錄時,系統會自動清空跟這個表相關的全部緩存記錄。當第二次查詢時,緩存中已經沒有這張表對應的緩存信息。此時就須要從新解析並查詢。操作系統
四是須要注意,默認字符集對緩存命中率的影響。一般狀況下,若是客戶端與服務器之間所採用的默認字符集不一樣,則即便查詢語句相同、在兩次查詢之間記錄與表結構也沒有被更改,系統仍然認爲是不一樣的查詢。對於這一點須要特別的注意,你們比較容易忽視。內存
2、提升緩存命中率的建議。class
從上面的條件分析中能夠看出,利用緩存中的數據具備比較嚴格的條件。其實這些條件也是合情合理的。主要是爲了保障數據的一致性。對以上這些條件有深刻的認識以後,如今數據庫管理員須要考慮的是,如何來提升這個緩存的命中率?對此筆者有以下幾個建議。效率
一是在配置時,客戶端與服務器端要使用相同的字符集。若是客戶端(或者說第三方工具)與服務器端使用的字符集不一樣,那麼任何狀況下都不會使用緩存功能。特別在國內,須要用到中文的字符集。此時特別須要注意,客戶端默認字符集要與服務器端的默認字符集相同。注意,這裏是相同,而不是兼容。有時候即便採用了不一樣的字符集,客戶端上仍然能夠正常顯示。這主要是由於有些字符集雖然不相同,可是是相互兼容的。在緩存管理上,須要相同,光兼容還不行。
二是在客戶端上,要固化查詢的語句。如如今有財務人員和採購人員同時從系統中查詢11月份的出貨數據。顯然他們崗位職責不一樣,所須要字段的內容是不一樣的。此時在客戶端出,能夠容許用戶設置本身所須要的表單格式。可是筆者建議,後臺所採用的SQL語句最好是相同的。這裏數據會通過三個渠道:後臺數據庫、客戶端、用戶。筆者的意識時,後臺數據庫與客戶端之間的交互採用相同的SQL語句。而後客戶端與用戶之間進行交互時,根據用戶定義的格式(包括字段先後的排列、不包括查詢條件語句的差別)向用戶顯示數據。此時因爲採用了相同的SQL語句(只是用戶對於顯示格式的要求不一樣),從而能夠提升應用系統的查詢效率。
三是提升內存中緩存的配置,來提升命中率。通常在服務器啓動時,操做系統會跟數據庫軟件協商緩存空間的大小。當緩存工做不足時,緩存中最舊的緩存記錄會被最新的消息所覆蓋。可見,若是可以提升緩存空間,就能夠提升命中率。這就好像打靶,目標多了,命中的概率也會高許多。不過用戶的併發數越多,這個設置的效果會越不明顯。
四是經過分區表能夠提升緩存的命中率。在上面的條件分析中,你們能夠看到,只要所查詢的表中插入了一條記錄,系統就會清空緩存記錄。如今以查詢出貨記錄爲例。出貨記錄表天天都在更新,而用戶在年初時,會常常須要查詢上一年的出貨記錄。此時因爲這個表中的數據每一個小時都在更新,那麼緩存中的信息會不斷的被狀況。此時緩存的命中率顯然不會很高。針對這種狀況,筆者建議能夠採用分區表。如能夠經過系統設置,將2010年的出貨記錄單獨存放在一個出貨的分區表中。即每個年度都使用一張單獨的分區表。此時2011年的紀錄,就不會影響到2010年的分區表。此時若是用戶重複查詢2010年的出貨信息,只要其使用的SQL語句相同(沒有采用不一樣的查詢條件),那麼就能夠享受緩存機制所帶來的效益,提升應用系統的查詢效果。。
3、多個應用對緩存的影響。
一般狀況下,MySQL數據庫的緩存是根據服務器內存的大小自動分配的。若是一臺服務器上只有一個MySQL應用,那麼當然最好。不過在實際工做中,爲了下降信息化投資的成本,每每會在同一臺服務器上佈置多個信息化應用。因爲其餘信息化應用也須要使用內存的空間做爲緩存,那麼MySQL數據庫中緩存空間就可能變小。若是遇到這種狀況下,數據庫管理員須要跟系統工程師進行協商,爲各類不一樣的應用根據性能要求的不一樣,手工設置不一樣的緩存空間。如此的話,就能夠避免同一臺服務器上不一樣信息化應用對緩存的衝突。