您的位置:首页 > 产品设计 > UI/UE

8.9.3 The MySQL Query Cache

2014-08-03 09:37 489 查看

8.9.3 The MySQL Query Cache

8.9.3.1 How the Query Cache
Operates8.9.3.2 Query Cache 
SELECT
 Options8.9.3.3 Query Cache Configuration8.9.3.4 Query Cache Status and
Maintenance

The query cache stores the text of a 
SELECT
 statement
together with the corresponding result that was sent to the client. If an identical statement is received later, the server retrieves the results from the query cache rather than parsing and executing the statement again. The query cache is shared among sessions,
so a result set generated by one client can be sent in response to the same query issued by another client.

The query cache can be useful in an environment where you have tables that do not change very often and for which the server receives many identical queries. This is a typical situation for many Web servers that generate many dynamic
pages based on database content.

The query cache does not return stale data. When tables are modified, any relevant entries in the query cache are flushed.

Note
The query cache does not work in an environment where you have multiple mysqld servers
updating the same
MyISAM
 tables.

The query cache is used for prepared statements under the conditions described in Section 8.9.3.1,
“How the Query Cache Operates”.

Note
The query cache is not supported for partitioned tables, and is automatically disabled for queries involving partitioned tables. The query cache cannot be enabled for such queries.

Some performance data for the query cache follows. These results were generated by running the MySQL benchmark suite on a Linux Alpha 2×500MHz system with 2GB RAM and a 64MB query cache.

If all the queries you are performing are simple (such as selecting a row from a table with one row), but still differ so that the queries cannot be cached, the overhead for having the query cache active is 13%. This could be regarded
as the worst case scenario. In real life, queries tend to be much more complicated, so the overhead normally is significantly lower.

Searches for a single row in a single-row table are 238% faster with the query cache than without it. This can be regarded as close to the minimum speedup to be expected for a query that is cached.

To disable the query cache at server startup, set the 
query_cache_size
 system
variable to 0. By disabling the query cache code, there is no noticeable overhead.

The query cache offers the potential for substantial performance improvement, but do not assume that it will do so under all circumstances. With some query cache configurations or server workloads, you might actually see a performance
decrease:

Be cautious about sizing the query cache excessively large, which increases the overhead required to maintain the cache, possibly beyond the benefit of enabling it. Sizes in tens of megabytes are usually beneficial. Sizes in the hundreds
of megabytes might not be.

Server workload has a significant effect on query cache efficiency. A query mix consisting almost entirely of a fixed set of 
SELECT
 statements
is much more likely to benefit from enabling the cache than a mix in which frequent
INSERT
 statements
cause continual invalidation of results in the cache. In some cases, a workaround is to use the
SQL_NO_CACHE
 option
to prevent results from even entering the cache for 
SELECT
 statements
that use frequently modified tables. (See Section 8.9.3.2,
“Query Cache 
SELECT
 Options”.)

To verify that enabling the query cache is beneficial, test the operation of your MySQL server with the cache enabled and disabled. Then retest periodically because query cache efficiency may change as server workload changes.

8.9.3.1 How the Query Cache Operates

This section describes how the query cache works when it is operational. Section 8.9.3.3,
“Query Cache Configuration”, describes how to control whether it is operational.

Incoming queries are compared to those in the query cache before parsing, so the following two queries are regarded as different by the query cache:

SELECT * FROM [code]tbl_name

Select * from
tbl_name

[/code]
Queries must be exactly the same (byte for byte) to be seen as identical. In addition, query strings that are identical may be treated as different for other reasons.
Queries that
4000
use different databases, different protocol versions, or different default character sets are considered different queries and are cached separately.

The cache is not used for queries of the following types:

Queries that are a subquery of an outer query

Queries executed within the body of a stored function, trigger, or event

Before a query result is fetched from the query cache, MySQL checks whether the user has 
SELECT
 privilege
for all databases and tables involved. If this is not the case, the cached result is not used.

If a query result is returned from query cache, the server increments the 
Qcache_hits
 status
variable, not
Com_select
. See Section 8.9.3.4,
“Query Cache Status and Maintenance”.

If a table changes, all cached queries that use the table become invalid and are removed from the cache. This includes queries that use 
MERGE
 tables
that map to the changed table. A table can be changed by many types of statements, such as 
INSERT
UPDATE
DELETE
TRUNCATE
TABLE
ALTER
TABLE
DROP
TABLE
, or 
DROP
DATABASE
.

The query cache also works within transactions when using 
InnoDB
 tables.

In MySQL 5.7, the result from a 
SELECT
 query
on a view is cached.

The query cache works for 
SELECT SQL_CALC_FOUND_ROWS ...
 queries and stores a value that
is returned by a following 
SELECT FOUND_ROWS()
 query. 
FOUND_ROWS()
 returns
the correct value even if the preceding query was fetched from the cache because the number of found rows is also stored in the cache. The 
SELECT
FOUND_ROWS()
 query itself cannot be cached.

Prepared statements that are issued using the binary protocol using 
mysql_stmt_prepare()
 and
mysql_stmt_execute()
 (see Section 22.8.8,
“C API Prepared Statements”), are subject to limitations on caching. Comparison with statements in the query cache is based on the text of the statement after expansion of 
?
parameter
markers. The statement is compared only with other cached statements that were executed using the binary protocol. That is, for query cache purposes, prepared statements issued using the binary protocol are distinct from prepared statements issued using the
text protocol (see Section 13.5,
“SQL Syntax for Prepared Statements”).

A query cannot be cached if it contains any of the functions shown in the following table.

AES_DECRYPT()
 (as
of 5.7.4)
AES_ENCRYPT()
 (as
of 5.7.4)
BENCHMARK()
CONNECTION_ID()
CONVERT_TZ()
CURDATE()
CURRENT_DATE()
CURRENT_TIME()
CURRENT_TIMESTAMP()
CURTIME()
DATABASE()
ENCRYPT()
 with
one parameter
FOUND_ROWS()
GET_LOCK()
LAST_INSERT_ID()
LOAD_FILE()
MASTER_POS_WAIT()
NOW()
PASSWORD()
RAND()
RANDOM_BYTES()
RELEASE_LOCK()
SLEEP()
SYSDATE()
UNIX_TIMESTAMP()
 with
no parameters
USER()
UUID()
UUID_SHORT()
  
A query also is not cached under these conditions:

It refers to user-defined functions (UDFs) or stored functions.

It refers to user variables or local stored program variables.

It refers to tables in the 
mysql
INFORMATION_SCHEMA
,
or 
performance_schema
 database.

It refers to any partitioned tables.

It is of any of the following forms:

SELECT ... LOCK IN SHARE MODE
SELECT ... FOR UPDATE
SELECT ... INTO OUTFILE ...
SELECT ... INTO DUMPFILE ...
SELECT * FROM ... WHERE autoincrement_col IS NULL

The last form is not cached because it is used as the ODBC workaround for obtaining the last insert ID value. See the Connector/ODBC section of Chapter 22, Connectors
and APIs.

Statements within transactions that use 
SERIALIZABLE
 isolation
level also cannot be cached because they use
LOCK IN SHARE MODE
 locking.

It uses 
TEMPORARY
 tables.

It does not use any tables.

It generates warnings.

The user has a column-level privilege for any of the involved tables.

8.9.3.2 Query Cache 
SELECT
 Options

Two query cache-related options may be specified in 
SELECT
 statements:

 
SQL_CACHE


The query result is cached if it is cacheable and the value of the 
query_cache_type
 system
variable is 
ON
 or
DEMAND
.

SQL_NO_CACHE


The server does not use the query cache. It neither checks the query cache to see whether the result is already cached, nor does it cache the query result.

Examples:

SELECT SQL_CACHE id, name FROM customer;
SELECT SQL_NO_CACHE id, name FROM customer;


8.9.3.3 Query Cache Configuration

The 
have_query_cache
 server
system variable indicates whether the query cache is available:

mysql> [code]SHOW VARIABLES LIKE 'have_query_cache';

+------------------+-------+
| Variable_name | Value |
+------------------+-------+
| have_query_cache | YES |
+------------------+-------+
[/code]
When using a standard MySQL binary, this value is always 
YES
, even if query caching is
disabled.

Several other system variables control query cache operation. These can be set in an option file or on the command line when starting mysqld.
The query cache system variables all have names that begin with
query_cache_
. They are described briefly in Section 5.1.4,
“Server System Variables”, with additional configuration information given here.

To set the size of the query cache, set the 
query_cache_size
 system
variable. Setting it to 0 disables the query cache, as does setting 
query_cache_type=0
.
By default, the query cache is disabled. This is achieved using a default size of 1M, with a default for 
query_cache_type
 of
0.

To reduce overhead significantly, also start the server with 
query_cache_type=0
 if
you will not be using the query cache.

Note
When using the Windows Configuration Wizard to install or configure MySQL, the default value for
query_cache_size
 will
be configured automatically for you based on the different configuration types available. When using the Windows Configuration Wizard, the query cache may be enabled (that is, set to a nonzero value) due to the selected configuration. The query cache is also
controlled by the setting of the 
query_cache_type
variable.
Check the values of these variables as set in your 
my.ini
 file after configuration has taken place.

When you set 
query_cache_size
 to
a nonzero value, keep in mind that the query cache needs a minimum size of about 40KB to allocate its structures. (The exact size depends on system architecture.) If you set the value too small, you'll get a warning, as in this example:

mysql> [code]SET GLOBAL query_cache_size = 40000;

Query OK, 0 rows affected, 1 warning (0.00 sec)

mysql>
SHOW WARNINGS\G

*************************** 1. row ***************************
Level: Warning
Code: 1282
Message: Query cache failed to set size 39936;
new query cache size is 0

mysql>
SET GLOBAL query_cache_size = 41984;

Query OK, 0 rows affected (0.00 sec)

mysql>
SHOW VARIABLES LIKE 'query_cache_size';

+------------------+-------+
| Variable_name | Value |
+------------------+-------+
| query_cache_size | 41984 |
+------------------+-------+
[/code]
For the query cache to actually be able to hold any query results, its size must be set larger:

mysql> [code]SET GLOBAL query_cache_size = 1000000;

Query OK, 0 rows affected (0.04 sec)

mysql>
SHOW VARIABLES LIKE 'query_cache_size';

+------------------+--------+
| Variable_name | Value |
+------------------+--------+
| query_cache_size | 999424 |
+------------------+--------+
1 row in set (0.00 sec)
[/code]
The 
query_cache_size
 value
is aligned to the nearest 1024 byte block. The value reported may therefore be different from the value that you assign.

If the query cache size is greater than 0, the 
query_cache_type
 variable
influences how it works. This variable can be set to the following values:

A value of 
0
 or 
OFF
 prevents
caching or retrieval of cached results.

A value of 
1
 or 
ON
 enables
caching except of those statements that begin with 
SELECT SQL_NO_CACHE
.

A value of 
2
 or 
DEMAND
 causes
caching of only those statements that begin with 
SELECT SQL_CACHE
.

If 
query_cache_size
 is
0, you should also set 
query_cache_type
 variable
to 0. In this case, the server does not acquire the query cache mutex at all, which means that the query cache cannot be enabled at runtime and there is reduced overhead in query execution.

Setting the 
GLOBAL
 
query_cache_type
 value
determines query cache behavior for all clients that connect after the change is made. Individual clients can control cache behavior for their own connection by setting the 
SESSION
query_cache_type
 value.
For example, a client can disable use of the query cache for its own queries like this:

mysql> [code]SET SESSION query_cache_type = OFF;

[/code]
If you set 
query_cache_type
 at
server startup (rather than at runtime with a 
SET
 statement),
only the numeric values are permitted.

To control the maximum size of individual query results that can be cached, set the 
query_cache_limit
 system
variable. The default value is 1MB.

Be careful not to set the size of the cache too large. Due to the need for threads to lock the cache during updates, you may see lock contention issues with a very large cache.

Note
You can set the maximum size that can be specified for the query cache at runtime with the 
SET
 statement
by using the 
--maximum-query_cache_size=32M
 option
on the command line or in the configuration file.

When a query is to be cached, its result (the data sent to the client) is stored in the query cache during result retrieval. Therefore the data usually is not handled in one big chunk. The query cache allocates blocks for storing
this data on demand, so when one block is filled, a new block is allocated. Because memory allocation operation is costly (timewise), the query cache allocates blocks with a minimum size given by the
query_cache_min_res_unit
 system
variable. When a query is executed, the last result block is trimmed to the actual data size so that unused memory is freed. Depending on the types of queries your server executes, you might find it helpful to tune the value of 
query_cache_min_res_unit
:

The default value of 
query_cache_min_res_unit
 is
4KB. This should be adequate for most cases.

If you have a lot of queries with small results, the default block size may lead to memory fragmentation, as indicated by a large number of free blocks. Fragmentation can force the query cache to prune (delete) queries from the cache
due to lack of memory. In this case, decrease the value of 
query_cache_min_res_unit
.
The number of free blocks and queries removed due to pruning are given by the values of the 
Qcache_free_blocks
and 
Qcache_lowmem_prunes
 status
variables.

If most of your queries have large results (check the 
Qcache_total_blocks
 and 
Qcache_queries_in_cache
status
variables), you can increase performance by increasing 
query_cache_min_res_unit
.
However, be careful to not make it too large (see the previous item).

8.9.3.4 Query Cache Status and Maintenance

To check whether the query cache is present in your MySQL server, use the following statement:

mysql> [code]SHOW VARIABLES LIKE 'have_query_cache';

+------------------+-------+
| Variable_name | Value |
+------------------+-------+
| have_query_cache | YES |
+------------------+-------+
[/code]
You can defragment the query cache to better utilize its memory with the 
FLUSH
QUERY CACHE
 statement. The statement does not remove any queries from the cache.

The 
RESET QUERY CACHE
 statement removes all query results from the query cache. The 
FLUSH
TABLES
statement also does this.

To monitor query cache performance, use 
SHOW
STATUS
 to view the cache status variables:

mysql> [code]SHOW STATUS LIKE 'Qcache%';

+-------------------------+--------+
| Variable_name | Value |
+-------------------------+--------+
| 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 |
+-------------------------+--------+
[/code]
Descriptions of each of these variables are given in Section 5.1.6,
“Server Status Variables”. Some uses for them are described here.

The total number of 
SELECT
 queries
is given by this formula:

Com_select
+ Qcache_hits
+ queries with errors found by parser

The 
Com_select
 value is given by this formula:

Qcache_inserts
+ Qcache_not_cached
+ queries with errors found during the column-privileges check

The query cache uses variable-length blocks, so 
Qcache_total_blocks
 and 
Qcache_free_blocks
 may
indicate query cache memory fragmentation. After 
FLUSH
QUERY CACHE
, only a single free block remains.

Every cached query requires a minimum of two blocks (one for the query text and one or more for the query results). Also, every table that is used by a query requires one block. However, if two or more queries use the same table,
only one table block needs to be allocated.

The information provided by the 
Qcache_lowmem_prunes
 status
variable can help you tune the query cache size. It counts the number of queries that have been removed from the cache to free up memory for caching new queries. The query cache uses a least recently used (LRU) strategy to decide which queries to remove from
the cache. Tuning information is given in Section 8.9.3.3,
“Query Cache Configuration”.

8.9.4 Caching of Prepared Statements and Stored Programs

For certain statements that a client might execute multiple times during a session, the server converts the statement to an internal structure and caches that structure to be used during execution. Caching enables the server to perform
more efficiently because it avoids the overhead of reconverting the statement should it be needed again during the session. Conversion and caching occurs for these statements:

Prepared statements, both those processed at the SQL level (using the 
PREPARE
 statement)
and those processed using the binary client/server protocol (using the 
mysql_stmt_prepare()
 C
API function). The
max_prepared_stmt_count
 system
variable controls the total number of statements the server caches. (The sum of the number of prepared statements across all sessions.)

Stored programs (stored procedures and functions, triggers, and events). In this case, the server converts and caches the entire program body. The 
stored_program_cache
 system
variable indicates the approximate number of stored programs the server caches per session.

The server maintains caches for prepared statements and stored programs on a per-session basis. Statements cached for one session are not accessible to other sessions. When a session ends, the server discards any statements cached
for it.

When the server uses a cached internal statement structure, it must take care that the structure does not go out of date. Metadata changes can occur for an object used by the statement, causing a mismatch between the current object
definition and the definition as represented in the internal statement structure. Metadata changes occur for DDL statements such as those that create, drop, alter, rename, or truncate tables, or that analyze, optimize, or repair tables. Table content changes
(for example, with 
INSERT
 or 
UPDATE
)
do not change metadata, nor do 
SELECT
 statements.

Here is an illustration of the problem. Suppose that a client prepares this statement:

PREPARE s1 FROM 'SELECT * FROM t1';

The 
SELECT *
 expands in the internal structure to the list of columns in the table. If
the set of columns in the table is modified with 
ALTER TABLE
, the prepared statement goes out of date. If the server
does not detect this change the next time the client executes 
s1
, the prepared statement will return incorrect results.

To avoid problems caused by metadata changes to tables or views referred to by the prepared statement, the server detects these changes and automatically reprepares the statement when it is next executed. That is, the server reparses
the statement and rebuilds the internal structure. Reparsing also occurs after referenced tables or views are flushed from the table definition cache, either implicitly to make room for new entries in the cache, or explicitly due to 
FLUSH
TABLES
.

Similarly, if changes occur to objects used by a stored program, the server reparses affected statements within the program.

The server also detects metadata changes for objects in expressions. These might be used in statements specific to stored programs, such as 
DECLARE
CURSOR
 or flow-control statements such as 
IF
CASE
,
and 
RETURN
.

To avoid reparsing entire stored programs, the server reparses affected statements or expressions within a program only as needed. Examples:

Suppose that metadata for a table or view is changed. Reparsing occurs for a 
SELECT *
 within
the program that accesses the table or view, but not for a 
SELECT *
 that does not access the table or view.

When a statement is affected, the server reparses it only partially if possible. Consider this 
CASE
 statement:

CASE [code]case_expr

WHEN
when_expr1
...
WHEN
when_expr2
...
WHEN
when_expr3
...
...
END CASE
[/code]
If a metadata change affects only 
WHEN when_expr3
,
that expression is reparsed. 
case_expr
 and
the other
WHEN
 expressions are not reparsed.

Reparsing uses the default database and SQL mode that were in effect for the original conversion to internal form.

The server attempts reparsing up to three times. An error occurs if all attempts fail.

Reparsing is automatic, but to the extent that it occurs, diminishes prepared statement and stored program performance.

For prepared statements, the 
Com_stmt_reprepare
 status
variable tracks the number of repreparations.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: