標籤:
為了提高查詢速度,Mysql會維護一個記憶體地區(官方文檔指出,大小至少41984B)對查詢結果進行緩衝,當查詢時發現緩衝區裡有資料則直接返回結果而不用去執行sql語句。
查詢命中的條件
每個緩衝查詢至少需要兩個塊(一個塊用於查詢文本,一個或多個塊用於查詢結果)。並且,每一個查詢使用的每個表需要一個塊。但是,如果兩個或多個查詢使用相同的表,僅需要分配一個塊。
對於兩個查詢語句是否相同的判定,Mysql是比較嚴格,查詢必須是完全相同的(逐位元組相同)才能夠被認為是相同的。另外,同樣的查詢字串由於其它原因可能認為是不同的。使用不同的資料庫、不同的協議版本或者不同 預設字元集的查詢被認為是不同的查詢並且分別進行緩衝。例如,以下兩個查詢是不相同的:
SELECT * FROM tbl_name |
Select * from tbl_name |
緩衝區配置
在Mysql中,設定緩衝區大小命令為:
| mysql>SET GLOBAL query_cache_size = 41984; |
如果設定的query_cache_size小於41984,則會設定失敗,並自動把它置為0。如果設定為0則表示不使用緩衝區。
當query_cache_size大於0的情況下,並不能保證緩衝區會被使用,還必鬚根據變數query_cache_type來決定,該變數有3中狀態,分別代表3中不同緩衝方式:
- 0或OFF--------將阻止緩衝或查詢快取結果。
|
- 1或ON---------將允許緩衝,以SELECT SQL_NO_CACHE開始的查詢語句除外。
|
- 2或DEMAND--------僅對以SELECT SQL_CACHE開始的那些查詢語句啟用緩衝。
|
設定方式如下:
| mysql> SET SESSION query_cache_type = OFF; |
查詢結果的記憶體大小分配
要控制可以被緩衝的具體查詢結果的最大值,應設定query_cache_limit變數。 預設值是1MB。
當一個查詢結果(返回給用戶端的資料)從查詢緩衝中提取期間,它在查詢快取中排序。因此,資料通常不在大的資料區塊中處理。查詢快取根據資料排序要求分配資料區塊,因此,當一個資料區塊用完後分配一個新的資料區塊。因為記憶體配置操作是昂貴的(費時的),所以通過query_cache_min_res_unit系統變數給查詢快取分配最小值。當查詢執行時,最新的結果資料區塊根據實際資料大小來確定,因此可以釋放不使用的記憶體。根據你的伺服器執行查詢的類型,你會發現調整query_cache_min_res_unit變數的值是有用的:
- query_cache_min_res_unit預設值是4KB。這應該適合大部分情況。
- 如果你有大量返回小結果資料的查詢,預設資料區塊大小可能會導致記憶體片段,顯示為大量空閑記憶體塊。由於缺少記憶體,記憶體片段會強制查詢快取從緩衝記憶體中修整(刪除)查詢。這時,你應該減少query_cache_min_res_unit變數的值。空閑塊和由於修整而移出的查詢的數量通過Qcache_free_blocks和Qcache_lowmem_prunes變數的值給出。
- 如果大量查詢返回大結果(檢查 Qcache_total_blocks和Qcache_queries_in_cache狀態變數),你可以通過增加query_cache_min_res_unit變數的值來提高效能。但是,注意不要使它變得太大。
也就是說,則給查詢結果分配緩衝區大小時,並不是再等待查詢結果返回後根據結果大小來分配空間,而是先根據query_cache_min_res_unit分配一個記憶體,待結果返回後直接放入記憶體中。這時候分3種情況考慮:
- 如果(查詢結果的大小=query_cache_min_res_unit),則直接把結果存入到該緩衝區中。
- 如果(查詢結果的大小<query_cache_min_res_unit),則直接把結果存入到該緩衝區中,然後把多分配的空間釋放掉,這種情況容易產生記憶體片段。
- 如果(查詢結果的大小>query_cache_min_res_unit),則需要再分配記憶體空間來存放結果
查詢高速緩衝狀態和維護
可以使用下面的語句檢查MySQL伺服器是否提供查詢快取功能:
mysql> SHOW VARIABLES LIKE ‘have_query_cache‘;
+------------------+-------+
| Variable_name | Value |
+------------------+-------+
| have_query_cache | YES |
+------------------+-------+
可以使用FLUSH QUERY CACHE語句來清理查詢快取片段以提高記憶體使用量效能。該語句不從緩衝中移出任何查詢。
RESET QUERY CACHE語句從查詢快取中移出所有查詢。FLUSH TABLES語句也執行同樣的工作。
為了監視查詢快取效能,使用SHOW STATUS查看緩衝狀態變數:
mysql> SHOW STATUS LIKE ‘Qcache%‘;
+-------------------------+--------+
|變數名 |值 |
+-------------------------+--------+
| Qcache_free_blocks | 36 |
| Qcache_free_memory | 138488 |
| Qcache_hits | 79570 |
| Qcache_inserts | 27087 |
| Qcache_lowmem_prunes | 3114 |
| Qcache_not_cached | 22989 |
| Qcache_queries_in_cache | 415 |
| Qcache_total_blocks | 912 |
+-------------------------+--------+
清除緩衝區釋放空間
查詢快取使用長度可變塊,因此Qcache_total_blocks和Qcache_free_blocks可以顯示查詢快取記憶體片段。執行FLUSH QUERY CACHE後,只保留一個空閑塊。
mysql>FLUSH QUERY CACHE;
記憶體置換策略
查詢緩衝區使用最近最少使用(LRU)策略來確定哪些查詢從緩衝區中移出(根據Qcache_lowmem_prunes狀態變數提供的資訊能夠協助你你調整查詢快取的大小。它計算為了緩衝新的查詢而從查詢緩衝區中移出到自由記憶體中的查詢的數目)
Mysql查詢快取區