MySQL查詢高速緩沖
查詢緩存會存儲SELECT查詢的文本以及發送給客戶端的相應結果。如果隨後收到一個相同的查詢,服務器從查詢緩存中重新得到查詢結果,而不再需要解析和執行查詢。如果有一個不經常改變的表並且服務器收到該表的大量相同查詢,查詢緩存在這樣的應用環境中十分有用。
對於許多Web服務器來說存在這種典型情況,它根據數據庫內容生成大量的動態頁面。查詢緩存不返回舊的數據。當表更改後,查詢緩存值的相關條目被清空。如果有許多mysqld服務器更新相同的MyISAM表,在這種情況下查詢緩存不起作用。
查詢緩存不適用於服務器方編寫的語句。如果正在使用服務器方編寫的語句,要考慮到這些語句將不會應用查詢緩存。
服務器啟動時要禁用查詢緩存,設置query_cache_size系統變量為0。禁用查詢緩存代碼後,沒有明顯的速度提高。編譯MySQL時,通過在configure中使用--without-query-cache選項,可以從服務器中徹底去除查詢緩存能力。
查詢高速緩沖如何工作
查詢解析之前進行比較,因此下面的兩個查詢被查詢緩存認為是不相同的: SELECT * FROM tbl_name Select * from tbl_name 查詢必須是完全相同的(逐字節相同)才能夠被認為是相同的。
另外,同樣的查詢字符串由於其它原因可能認為是不同的。使用不同的數據庫、不同的協議版本或者不同 默認字符集的查詢被認為是不同的查詢並且分別進行緩存。
從查詢緩存中提取一個查詢之前,MySQL檢查用戶對所有相關數據庫和表的SELECT權限。如果沒有權限,不使用緩存結果。如果從查詢緩存中返回一個查詢結果,服務器把Qcache_hits狀態變量的值加一,而不是Com_select變量。
如果一個表被更改了,那麼使用那個表的所有緩沖查詢將不再有效,並且從緩沖區中移出。這包括那些映射到改變了的表的使用MERGE表的查詢。一個表可以被許多類型的語句更改,例如INSERT、UPDATE、DELETE、TRUNCATE、ALTER TABLE、DROP TABLE或DROP DATABASE。COMMIT執行完後,被更改的事務InnoDB表不再有效。使用InnoDB表時,查詢緩存也在事務中工作,使用該表的版本號來檢測其內容是否仍舊是當前的。
視圖產生的查詢被緩存。SELECT SQL_CALC_FOUND_ROWS ...和SELECT FOUND_ROWS() type類型的查詢使用查詢緩存。即使因創建的行數也被保存在緩沖區內,前面的查詢從緩存中提取,FOUND_ROWS()也返回正確的值。
如果一個查詢包含下面函數中的任何一個,它不會被緩存: BENCHMARK() CONNECTION_ID() CURDATE() CURRENT_DATE() CURRENT_TIME() CURRENT_TIMESTAMP() CURTIME() DATABASE() 帶一個參數的ENCRYPT() FOUND_ROWS() GET_LOCK() LAST_INSERT_ID() LOAD_FILE() MASTER_POS_WAIT() NOW() RAND() RELEASE_LOCK() SYSDATE() 不帶參數的UNIX_TIMESTAMP() USER()
在下面的這些條件下,查詢也不會被緩存:引用自定義函數(UDFs)。引用自定義變量。引用mysql系統數據庫中的表。
下面方式中的任何一種: SELECT ...IN SHARE MODE SELECT ...FOR UPDATE SELECT ...INTO OUTFILE ... SELECT ...INTO DUMPFILE ... SELECT * FROM ...WHERE autoincrement_col IS NULL 最後一種方式不能被緩存是因為它被用作為ODBC工作區來獲取最近插入的ID值。
查詢高速緩沖配置
通過have_query_cache服務器系統變量指示查詢緩存是否可用: mysql> SHOW VARIABLES LIKE 'have_query_cache'; +------------------+-------+| Variable_name | Value | have_query_cache | YES |
+------------------+-------+ 即使禁用查詢緩存,當使用標准 MySQL二進制時,這個值總是YES。
其它幾個系統變量控制查詢緩存操作。當啟動mysqld時,這些變量可以在選項文件或者命令行中設置。所有查詢緩存系統變量名以query_cache_ 開頭。
為了設置查詢緩存大小,設置query_cache_size系統變量。設置為0表示禁用查詢緩存。 默認緩存大小設置為0;也就是禁用查詢緩存。當設置query_cache_size變量為非零值時,應記住查詢緩存至少大約需要40KB來分配其數據結構。(具體大小取決於系統結構) mysql> SET GLOBAL query_cache_size = 1000000; Query OK, 0 rows affected, 1 warning (0.00 sec)
如果查詢緩存大小設置為大於0,query_cache_type變量影響其工作方式。這個變量可以設置為下面的值: 0或OFF將阻止緩存或查詢緩存結果. 1或ON將允許緩存,以SELECT SQL_NO_CACHE開始的查詢語句除外。 2或DEMAND,僅對以SELECT SQL_CACHE開始的那些查詢語句啟用緩存。
查詢高速緩沖狀態和維護
可以使用FLUSH QUERY CACHE語句來清理查詢緩存碎片以提高內存使用性能。該語句不從緩存中移出任何查詢。 RESET QUERY CACHE語句從查詢緩存中移出所有查詢。FLUSH TABLES語句也執行同樣的工作。
為了監視查詢緩存性能,使用SHOW STATUS查看緩存狀態變量: