top
Loading...
5.13.1.查詢高速緩沖如何工作
5.13.1. 查詢高速緩沖如何工作

本節描述查詢緩存的工作原理。5.13.3節,“查詢高速緩沖配置”描述了怎樣控制是否使用查詢緩存。

查詢解析之前進行比較,因此下面的兩個查詢被查詢緩存認為是不相同的:

SELECT * FROM tbl_name
Select * from tbl_name

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

從查詢緩存中提取一個查詢之前,MySQL檢查用戶對所有相關數據庫和表的SELECT權限。如果沒有權限,不使用緩存結果。

如果從查詢緩存中返回一個查詢結果,服務器把Qcache_hits狀態變量的值加一,而不是Com_select變量。參見5.13.4節,“查詢高速緩沖狀態和維護”。

如果一個表被更改了,那么使用那個表的所有緩沖查詢將不再有效,并且從緩沖區中移出。這包括那些映射到改變了的表的使用MERGE表的查詢。一個表可以被許多類型的語句更改,例如INSERTUPDATEDELETETRUNCATEALTER TABLEDROP TABLEDROP DATABASE

COMMIT執行完后,被更改的事務InnoDB表不再有效。

使用InnoDB表時,查詢緩存也在事務中工作,使用該表的版本號來檢測其內容是否仍舊是當前的。

MySQL 5.1中,視圖產生的查詢被緩存。

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值。參見26.1.14.1節,“如何在ODBC中獲取AUTO_INCREMENT列的值”。

·          被作為編寫好的語句,即使沒有使用占位符。例如,下面使用的查詢:

char *my_sql_stmt = "SELECT ab FROM table_c";
   /* ...*/
mysql_stmt_prepare(stmtmy_sql_stmtstrlen(my_sql_stmt));

不被緩存。參見25.2.4節,“C API預處理語句”。

·         使用TEMPORARY表。

·         不使用任何表。

·         用戶有某個表的列級權限。

作者:mysql.com
來源:http://dev.mysql.com/doc/refman/5.1/zh/database-administration.html
北斗有巢氏 有巢氏北斗