MySQL Advanced-MySQL query cache optimization

1 Overview

Turn on the query cache of Mysql. When the same SQL statement is executed, the server will directly read the results from the cache. When the data is modified, the previous cache will become invalid. Tables that are frequently modified are not suitable for query cache.

2 Operation process

Insert picture description here
1. The client sends a query to the server;
2. The server first checks the query cache, and if it hits the cache, it immediately returns the result stored in the cache. Otherwise, enter the next stage;
3. The server side performs SQL analysis and preprocessing, and then the optimizer generates the corresponding execution plan;
4. MySQL calls the storage engine API to execute the query according to the execution plan generated by the optimizer ;
5. The result is returned to the client.

3 Query cache configuration

  1. Check whether the current MySQL database supports query caching:
 SHOW VARIABLES LIKE 'have_query_cache';
mysql> SHOW VARIABLES LIKE 'have_query_cache';
+------------------+-------+
| Variable_name    | Value |
+------------------+-------+
| have_query_cache | YES   |
+------------------+-------+
1 row in set (0.26 sec)

Represents that the current database supports query caching

  1. Check whether the query cache is enabled in MySQL:
mysql>  SHOW VARIABLES LIKE 'query_cache_type';
+------------------+-------+
| Variable_name    | Value |
+------------------+-------+
| query_cache_type | OFF   |
+------------------+-------+
1 row in set (0.01 sec)

Indicates that the query cache is not currently enabled

  1. View the occupied size of the query cache:
mysql> SHOW VARIABLES LIKE 'query_cache_size';
+------------------+----------+
| Variable_name    | Value    |
+------------------+----------+
| query_cache_size | 16777216 |
+------------------+----------+

It means that the current query cache occupies 16777216 bytes, which is about 1.5MB. If the cache is too small, you can change the value of query_cache_size to increase the size of the query cache.

  1. View the state variables of the query cache:
mysql> SHOW STATUS LIKE 'Qcache%';
+-------------------------+----------+
| Variable_name           | Value    |
+-------------------------+----------+
| Qcache_free_blocks      | 1        |
| Qcache_free_memory      | 16768680 |
| Qcache_hits             | 0        |
| Qcache_inserts          | 0        |
| Qcache_lowmem_prunes    | 0        |
| Qcache_not_cached       | 29       |
| Qcache_queries_in_cache | 0        |
| Qcache_total_blocks     | 1        |
+-------------------------+----------+

The meaning of each variable is as follows:

parameter meaning
Qcache_free_blocks Query the number of free memory blocks in the cache
Qcache_free_memory The amount of memory available for query cache
Qcache_hits Query cache hits
Qcache_inserts Number of queries added to the query cache
Qcache_lowmen_prunes The number of queries deleted from the query cache due to insufficient memory
Qcache_not_cached The number of non-cached queries (cannot be cached or not cached due to the query_cache_type setting)
Qcache_queries_in_cache Number of queries registered in the query cache
Qcache_total_blocks Total number of blocks in the query cache

4 Turn on query cache

MySQL's query cache is turned off by default, and you need to manually configure the parameter query_cache_type to enable query cache. There are three possible values ​​for query_cache_type:

value meaning
OFF or 0 Query cache function is off
ON or 1 When the query cache function is turned on, the result of SELECT will be cached if it meets the caching conditions. Otherwise, it will not be cached, and SQL_NO_CACHE will be explicitly specified and not cached
DEMAND or 2 The query cache function is performed on demand, and only SELECT statements that explicitly specify SQL_CACHE will be cached; others will not be cached

How to set the value of query_cache_type, here we need to modify the MySQL configuration file
blogger's Ubuntu (Linux operating system) version to 16.04, mysql version to 5.7. You need to enter /etc/mysql/mysql.conf.d to modify the configuration file mysqld.cnf to
Insert picture description here
add the following content
Insert picture description here
and then you need to restart the MySQL service

Log in to MySQL
Insert picture description here
again, you can then query whether the MySQL query cache is enabled
Insert picture description here

After the configuration is complete, restart the service to take effect;

Then you can execute the SQL statement on the command line for verification, execute a relatively time-consuming SQL statement, and then execute it a few more times to check the execution time of the next few times; get the cache hits of the query cache to determine whether to go Query the cache.

We can test. We once built a table tb_item with 2.5 million pieces of data.

mysql> select count(*) from tb_item;
+----------+
| count(*) |
+----------+
|  2499695 |
+----------+
1 row in set (8.57 sec)

mysql> select count(*) from tb_item;
+----------+
| count(*) |
+----------+
|  2499695 |
+----------+
1 row in set (0.00 sec)

As you can see, the first execution of 8s, the second execution of the same SQL statement, only need 0s
so that we can verify that the query cache is indeed enabled and effective.
We can see the cache status, the number of hits has been 1, and the number of times added to the cache is 1 (because the same SQL statement is only added in the first query)
Insert picture description here

5 Query cache SELECT option

Two options related to query caching can be specified in the SELECT statement:
SQL_CACHE: If the query result is cacheable and the value of the query_cache_type system variable is ON or DEMAND, the query result is cached.
SQL_NO_CACHE: The server does not use query cache. It neither checks the query cache, nor does it check whether the results are cached, nor does it cache the query results.

Note: When the value of the query_cache_type system variable is ON, it will be cached even if SQL_CACHE is not added, and the value of the query_cache_type variable is DEMAND. Only when SQL_CACHE is specified, the cache will be used.

The first two rows of the tb_item table are as follows

mysql> select * from tb_item limit 2;
+----+------------+----------+-------+------------+--------+------------+---------------------+---------------------+
| id | title      | price    | num   | categoryid | status | sellerid   | createtime          | updatetime          |
+----+------------+----------+-------+------------+--------+------------+---------------------+---------------------+
|  1 | 货物1号    | 33494.85 |   365 |          0 | 1      | 5435343235 | 2019-04-20 22:37:15 | 2019-04-20 22:37:15 |
|  2 | 货物2号    |  5617.72 | 24060 |          0 | 1      | 5435343235 | 2019-04-20 22:37:15 | 2019-04-20 22:37:15 |
+----+------------+----------+-------+------------+--------+------------+---------------------+---------------------+
2 rows in set (0.04 sec)

We test the query (note that the previous statement has been placed in the cache, and the corresponding state value will change)

mysql> select title,sellerid from tb_item where id=1;
+------------+------------+
| title      | sellerid   |
+------------+------------+
| 货物1号    | 5435343235 |
+------------+------------+
1 row in set (0.00 sec)

mysql> show status like 'Qcache%';
+-------------------------+----------+
| Variable_name           | Value    |
+-------------------------+----------+
| Qcache_free_blocks      | 1        |
| Qcache_free_memory      | 16764840 |
| Qcache_hits             | 1        |
| Qcache_inserts          | 3        |
| Qcache_lowmem_prunes    | 0        |
| Qcache_not_cached       | 3        |
| Qcache_queries_in_cache | 3        |
| Qcache_total_blocks     | 8        |
+-------------------------+----------+
8 rows in set (0.00 sec)

Explain that this statement has also been added to the cache

When I don’t want to do caching, we need to add SELECT_NO_CACHE after select

mysql> select SQL_NO_CACHE title,sellerid from tb_item where id=2;
+------------+------------+
| title      | sellerid   |
+------------+------------+
| 货物2号    | 5435343235 |
+------------+------------+
1 row in set, 1 warning (0.00 sec)

mysql> show status like 'Qcache%';
+-------------------------+----------+
| Variable_name           | Value    |
+-------------------------+----------+
| Qcache_free_blocks      | 1        |
| Qcache_free_memory      | 16764840 |
| Qcache_hits             | 1        |
| Qcache_inserts          | 3        |
| Qcache_lowmem_prunes    | 0        |
| Qcache_not_cached       | 4        |
| Qcache_queries_in_cache | 3        |
| Qcache_total_blocks     | 8        |
+-------------------------+----------+
8 rows in set (0.03 sec)

The value of Qcache_inserts is still 3, indicating that it is not cached.

6 Query cache invalidation

We have improved before, when the value of query_cache_type is set to 1, it will cache the results of select statements that meet the conditions. The reason is because in some cases, the query cache will be invalid.

1) In the case of inconsistent SQL statements, in order to hit the query cache, the query SQL statements must be completely consistent.

SQL1 : select count(*) from tb_item;
SQL2 : Select count(*) from tb_item;

Only the case is different.

mysql> select count(*) from tb_item;
+----------+
| count(*) |
+----------+
|  2499695 |
+----------+
1 row in set (0.00 sec)

mysql> Select count(*) from tb_item;
+----------+
| count(*) |
+----------+
|  2499695 |
+----------+
1 row in set (2.02 sec)

2) When there are some uncertainties in the query statement, it will not be cached. Such as: now(), current_date(), curdate(), curtime(), rand(), uuid(), user(), database(). The results obtained by these functions are different each time.

SQL1 : select * from tb_item where updatetime < now() limit 1;
SQL2 : select user();
SQL3 : select database();

3) Do not use any table query statements.
For example, select a constant select'hello';

select 'A';

4) When querying tables in mysql, information_schema or performance_schema system databases, the query cache will not be used.
MySQL system database includes mysql, information_schema or performance_schema

select * from information_schema.engines;

5) Queries executed within the body of stored functions, triggers or events.

6) If the table changes, all cache queries using the table will become invalid and deleted from the cache. This includes MERGEqueries that use tables mapped to changed tables. A table can be changed by many types of statements, such as INSERT, UPDATE, DELETE, TRUNCATE TABLE, ALTER TABLE, DROP TABLE, or DROP DATABASE.

mysql> Select count(*) from tb_item;
+----------+
| count(*) |
+----------+
|  2499695 |
+----------+
1 row in set (0.00 sec)

mysql> update tb_item set title='test1' where id=5;
Query OK, 1 row affected (0.05 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql> Select count(*) from tb_item;
+----------+
| count(*) |
+----------+
|  2499695 |
+----------+
1 row in set (1.23 sec)

mysql> Select count(*) from tb_item;
+----------+
| count(*) |
+----------+
|  2499695 |
+----------+
1 row in set (0.00 sec)

Guess you like

Origin blog.csdn.net/qq_39736597/article/details/113187656