Article directory
1. Introduction to the article
When we operate the database, we often use mysql
some defined variables or formats.
For example, if we have a user
table, the format of querying the creation time of the table ( create_time
) is yyyy年MM月dd日 HH时mm分ss秒
, but mysql
the queried creation time is 2023-03-01 19:03:04
, as shown in the following code:
mysql> select username as 用户名,create_time as 创建时间 from user where username = '陈希尔';
+--------+---------------------+
| 用户名 | 创建时间 |
+--------+---------------------+
| 陈希尔 | 2023-03-01 19:03:04 |
+--------+---------------------+
1 row in set (0.00 sec)
We don't know MySQL
how to define this yyyy年MM月dd日 HH时mm分ss秒
format, so we need to use show variables like 'datetime_format'
statement query, as shown in the following code:
mysql> show variables like 'datetime_format';
+-----------------+-------------------+
| Variable_name | Value |
+-----------------+-------------------+
| datetime_format | %Y-%m-%d %H:%i:%s |
+-----------------+-------------------+
1 row in set, 1 warning (0.00 sec)
Although the format of the query is %Y-%m-%d %H:%i:%s
, we can replace it with %Y年%m月%d日 %H时%i分%s秒
, and then perform the following SQL
query:
select
username as 用户名,
DATE_FORMAT(create_time,'%Y年%m月%d日 %H时%i分%s秒') as 创建时间
from
`user`
where
username = '陈希尔';
+--------+-----------------------------+
| 用户名 | 创建时间 |
+--------+-----------------------------+
| 陈希尔 | 2023年03月01日 19时03分04秒 |
+--------+-----------------------------+
1 row in set (0.00 sec)
Therefore, we need to use show variables like xxx
to query MySQL
the defined format, and then I will analyze it in detail.
2. Introduction to show variables
We can use show variables;
to query MySQL
all the variables defined, but due to the queried 506行
data, as shown in the following figure:
Therefore, it is not possible to extract all the columns, and those who are interested can use show variables;
the query, as shown in the following code:
mysql> show variables;
+-----------------------------+------------------------+
| Variable_name | Value |
+-----------------------------+------------------------+
| auto_increment_increment | 1 |
| auto_increment_offset | 1 |
| autocommit | ON |
| automatic_sp_privileges | ON |
| avoid_temporal_upgrade | OFF |
| ... ... ... |
| wait_timeout | 28800 |
| warning_count | 0 |
+-----------------------------+------------------------+
506 rows in set, 1 warning (0.00 sec)
3. Introduction to show global status
show global status
Check MySQL
the various status values of the server operation, but due to the queried 353行
data, as shown in the following figure:
Therefore, it is not possible to extract all the columns, and those who are interested can use show global status
the query, as shown in the following code:
show global status;
+-----------------------------------+---------+
| Variable_name | Value |
+-----------------------------------+---------+
| Aborted_clients | 203 |
| Aborted_connects | 1 |
| Binlog_cache_disk_use | 0 |
| .... ... |
| Uptime | 969795 |
| Uptime_since_flush_status | 969795 |
+-----------------------------------+---------+
353 rows in set (0.00 sec)
3. Detailed introduction
3.1 Slow query
mysql> show variables like '%slow%';
+---------------------------+--------------------------+
| Variable_name | Value |
+---------------------------+--------------------------+
| log_slow_admin_statements | OFF |
| log_slow_slave_statements | OFF |
| slow_launch_time | 2 |
| slow_query_log | OFF |
| slow_query_log_file | DESKTOP-UVTEHFR-slow.log |
+---------------------------+--------------------------+
5 rows in set, 1 warning (0.00 sec)
mysql> show global status like '%slow%';
+---------------------+-------+
| Variable_name | Value |
+---------------------+-------+
| Slow_launch_threads | 0 |
| Slow_queries | 120 |
+---------------------+-------+
2 rows in set (0.00 sec)
Logging slow queries is turned off in the configuration, but it is better to turn it on for easy optimization.
After 2 seconds, it is a slow query, and there are a total of 120
slow queries.
3.2 Query the number of connections
mysql> show variables like 'max_connections';
+-----------------+-------+
| Variable_name | Value |
+-----------------+-------+
| max_connections | 1000 |
+-----------------+-------+
1 row in set, 1 warning (0.00 sec)
mysql> show global status like 'max_used_connections';
+----------------------+-------+
| Variable_name | Value |
+----------------------+-------+
| Max_used_connections | 750 |
+----------------------+-------+
1 row in set (0.00 sec)
The maximum number of connections set is 1000, and the number of connections responded is 750.
max_used_connections / max_connections * 100% = 75% (理想值 ≈ 85%)
3.3 key_buffer_size
mysql> show variables like 'key_buffer_size';
+-----------------+---------+
| Variable_name | Value |
+-----------------+---------+
| key_buffer_size | 8388608 |
+-----------------+---------+
1 row in set, 1 warning (0.00 sec)
key_buffer_size
It is MyISAM
a parameter that has the greatest impact on table performance, but it is mostly in the database Innodb
.
mysql> show global status like 'key_read%';
+-------------------+-------+
| Variable_name | Value |
+-------------------+-------+
| Key_read_requests | 270 |
| Key_reads | 5 |
+-------------------+-------+
2 rows in set (0.00 sec)
There are a total 270
of index read requests, and one 5
request is not found in the memory to directly read the index from the hard disk.
Calculate the probability of an index miss cache:
key_cache_miss_rate = Key_reads / Key_read_requests * 100% =1.85%.
It needs to be enlarged appropriately key_buffer_size
, as shown in the following code:
mysql> set global key_buffer_size= 83886080;
Query OK, 0 rows affected (0.00 sec)
Key_blocks_unused
Indicates the number of unused cache clusters ( blocks
), Key_blocks_used
and represents the largest blocks
number ever used.
mysql> show global status like 'key_blocks_u%';
+-------------------+-------+
| Variable_name | Value |
+-------------------+-------+
| Key_blocks_unused | 6693 |
| Key_blocks_used | 500 |
+-------------------+-------+
2 rows in set (0.00 sec)
Key_blocks_used / (Key_blocks_unused + Key_blocks_used) * 100% ≈ 7.5% (理想值 ≈ 80%)
3.4 Temporary table query
mysql> show global status like 'created_tmp%';
+-------------------------+-------+
| Variable_name | Value |
+-------------------------+-------+
| Created_tmp_disk_tables | 623 |
| Created_tmp_files | 21 |
| Created_tmp_tables | 1423 |
+-------------------------+-------+
3 rows in set (0.00 sec)
Each time a temporary table is created, Created_tmp_tables
it increases.
Created_tmp_disk_tables
Also increase if temporary tables are created on disk .
Created_tmp_files
Indicates MySQL
the number of temporary file files created by the service:
Created_tmp_disk_tables / Created_tmp_tables * 100% = 43.8% (理想值<= 25%)。
mysql> show variables where Variable_name in ('tmp_table_size', 'max_heap_table_size');
+---------------------+----------+
| Variable_name | Value |
+---------------------+----------+
| max_heap_table_size | 16777216 |
| tmp_table_size | 68157440 |
+---------------------+----------+
2 rows in set, 1 warning (0.00 sec)
It needs to be added tmp_table_size
, as shown in the following code:
mysql> set global tmp_table_size = 681574400;
Query OK, 0 rows affected (0.00 sec)
3.5 open table query
mysql> show global status like 'open%tables%';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| Open_tables | 529 |
| Opened_tables | 1447 |
+---------------+-------+
2 rows in set (0.00 sec)
Open_tables
Indicates the number of open tables.
Opened_tables
Indicates the number of tables that have been opened.
If Opened_tables
the number is too large, it means that the value in the configuration table_open_cache
( called before the version MySQL
) may be too small. Let's query the server value, as shown in the following code:5.1.3
table_cache
table_open_cache
mysql> show variables like 'table_open_cache';
+------------------+-------+
| Variable_name | Value |
+------------------+-------+
| table_open_cache | 2000 |
+------------------+-------+
1 row in set, 1 warning (0.00 sec)
Open_tables / Opened_tables * 100% =36.6% 理想值 (>= 85%)。
Open_tables / table_open_cache * 100% = 26.4% 理想值 (<= 95%)。
3.6 View process usage
mysql> show global status like 'Thread%';
+-------------------+-------+
| Variable_name | Value |
+-------------------+-------+
| Threads_cached | 12 |
| Threads_connected | 9 |
| Threads_created | 275 |
| Threads_running | 1 |
+-------------------+-------+
4 rows in set (0.00 sec)
If we MySQL
set it in the server configuration file thread_cache_size
, when the client is disconnected, the thread that the server handles this client will be cached to respond to the next client instead of being destroyed (provided that the number of caches does not reach the upper limit).
Threads_created
Indicates the number of threads created.
If Threads_created
the value is found to be too large, it means that MySQL
the server has been creating threads, which is also relatively resource-intensive.
You can appropriately increase the value in the configuration file thread_cache_size
and query the server thread_cache_size
configuration:
mysql> show variables like 'thread_cache_size';
+-------------------+-------+
| Variable_name | Value |
+-------------------+-------+
| thread_cache_size | 60 |
+-------------------+-------+
1 row in set, 1 warning (0.00 sec)
The setup thread_cache_size
code is as follows:
mysql> set global thread_cache_size = 100;
Query OK, 0 rows affected (0.00 sec)
3.7 query cache
mysql> show global status like 'qcache%';
+-------------------------+-------+
| Variable_name | Value |
+-------------------------+-------+
| Qcache_free_blocks | 0 |
| Qcache_free_memory | 0 |
| Qcache_hits | 0 |
| Qcache_inserts | 0 |
| Qcache_lowmem_prunes | 0 |
| Qcache_not_cached | 0 |
| Qcache_queries_in_cache | 0 |
| Qcache_total_blocks | 0 |
+-------------------------+-------+
8 rows in set (0.00 sec)
Qcache_free_blocks
: The number of adjacent memory blocks in the cache.
A large number indicates possible debris.
FLUSH QUERY CACHE
The defragmentation in the cache will be defragmented to get a free block.
-
Qcache_free_memory
: Free memory in the cache. -
Qcache_hits
: Incremented each time the query hits in the cache. -
Qcache_inserts
: It increases every time a query is inserted, and the number of hits divided by the number of insertions is the miss ratio. -
Qcache_lowmem_prunes
: The number of times the cache ran out of memory and had to be cleared to make room for more queries.
This number is best viewed over the long term.
If this number is growing, it may be very fragmented, or low on memory.
free_blocks
The sum above free_memory
can tell you which is the case.
-
Qcache_not_cached
: The number of queries that are not suitable for caching, usually because these queries are notSELECT
statements or usenow()
functions such as. -
Qcache_queries_in_cache
: The number of queries (and responses) currently cached. -
Qcache_total_blocks
: The number of blocks in the cache.
Let's check query_cache
the configuration of the server again:
mysql> show variables like 'query_cache%';
+------------------------------+---------+
| Variable_name | Value |
+------------------------------+---------+
| query_cache_limit | 1048576 |
| query_cache_min_res_unit | 4096 |
| query_cache_size | 0 |
| query_cache_type | OFF |
| query_cache_wlock_invalidate | OFF |
+------------------------------+---------+
5 rows in set, 1 warning (0.00 sec)
Explanation of each field:
-
query_cache_limit
: Queries larger than this size will not be cached. -
query_cache_min_res_unit
: The minimum size of the cache block. -
query_cache_size
: Query cache size. -
query_cache_type
: Cache type, which determines what kind of query is cached. In the example, it indicates thatselect sql_no_cache
the query . -
query_cache_wlock_invalidate
: When other clients areMyISAM
writing to the table, if the query is in progressquery cache
, whether to returncache
the result or wait for the write operation to complete before reading the table to obtain the result.
query_cache_min_res_unit
The configuration is one handle 双刃剑
. The default is that 4KB
a large setting value is good for large data queries, but if your queries are all small data queries, it is easy to cause memory fragmentation and waste.
查询缓存碎片率 = Qcache_free_blocks / Qcache_total_blocks * 100%.
If the query cache fragmentation rate exceeds 20%
, you can use FLUSH QUERY CACHE
the defragmentation cache, or reduce it query_cache_min_res_unit
, if your queries are all small data volumes.
查询缓存利用率 = (query_cache_size – Qcache_free_memory) / query_cache_size * 100%.
If the query cache utilization is 25%
below, it means that query_cache_size
the setting is too large and can be reduced appropriately.
The query cache utilization rate is 80%
above, and Qcache_lowmem_prunes > 50
if it is, query_cache_size
it may be a bit small, or there are too many fragments.
查询缓存命中率 = (Qcache_hits – Qcache_inserts) / Qcache_hits * 100%.
Example server:
-
Query Cache Fragmentation Rate = 20.46%
-
Query Cache Utilization = 62.26%
-
Query Cache Hit Ratio = 1.94%
It shows that the hit rate is very poor, maybe the write operation is more frequent, and there may be some fragments.
3.8 Sorting usage
mysql> show global status like 'sort%';
+-------------------+-------+
| Variable_name | Value |
+-------------------+-------+
| Sort_merge_passes | 8 |
| Sort_range | 247 |
| Sort_rows | 7021 |
| Sort_scan | 313 |
+-------------------+-------+
4 rows in set (0.00 sec)
Sort_merge_passes
It consists of two steps.
MySQL
It will first try to sort in memory, and the amount of memory used Sort_buffer_size
is determined .
If its size is not enough to read all the records into memory, MySQL
it will store the results of each sort in memory into a temporary file, and after MySQL
all the records are found, sort the records in the temporary file again.
This again sorts it up Sort_merge_passes
.
In fact, MySQL
another temporary file is used to store the resorted results, so it is common to see an Sort_merge_passes
increase of twice the number of temporary files created.
Because temporary files are used, the speed may be slower, and increasing the number of temporary files Sort_buffer_size
will be reduced Sort_merge_passes
and created.
But blindly increasing Sort_buffer_size
does not necessarily increase speed.
In addition, increasing the value of read_rnd_buffer_size
(3.2.3 is record_rnd_buffer_size
) also has a little benefit for sorting operations.
3.9 Number of open files (open_files)
mysql> show global status like 'open_files';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| Open_files | 47 |
+---------------+-------+
1 row in set (0.00 sec)
mysql> show variables like 'open_files_limit';
+------------------+-------+
| Variable_name | Value |
+------------------+-------+
| open_files_limit | 6209 |
+------------------+-------+
1 row in set, 1 warning (0.00 sec)
Appropriate settings:Open_files / open_files_limit * 100% <= 75%.
3.10 Query table lock situation
mysql> show global status like 'table_locks%';
+-----------------------+-------+
| Variable_name | Value |
+-----------------------+-------+
| Table_locks_immediate | 353 |
| Table_locks_waited | 0 |
+-----------------------+-------+
2 rows in set (0.00 sec)
Table_locks_immediate
Indicates the number of table locks to be released immediately.
Table_locks_waited
Indicates the number of table locks that need to wait.
If so Table_locks_immediate / Table_locks_waited > 5000
, it is best to use InnoDB
an engine, because InnoDB
it is a row lock MyISAM
rather than a table lock, and the application InnoDB
effect for high concurrent writing will be better.
3.11 Table scan situation
mysql> show global status like 'handler_read%';
+-----------------------+--------+
| Variable_name | Value |
+-----------------------+--------+
| Handler_read_first | 2470 |
| Handler_read_key | 16165 |
| Handler_read_last | 3 |
| Handler_read_next | 514168 |
| Handler_read_prev | 12 |
| Handler_read_rnd | 6302 |
| Handler_read_rnd_next | 942267 |
+-----------------------+--------+
7 rows in set (0.00 sec)
Call out the number of query requests completed by the server:
mysql> show global status like 'com_select';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| Com_select | 5556 |
+---------------+-------+
1 row in set (0.00 sec)
Calculate table scan rate:
表扫描率 = Handler_read_rnd_next / Com_select
If the table scan rate is too high 4000
, it means that too many table scans have been performed, and it is very likely that the index has not been built.
There is some benefit to increasing read_buffer_size
the value, but it's best not to exceed it 8MB
.
4. Introduction to set global 'xxx'=value
set global ‘xxx’=value
Set the value of the variable.
For example, if I want to enable slow query logging ( slow_query_log
), I can do this:
- First check
slow_query_log
whether it is enabled, as shown in the following code:
mysql> show variables like 'slow_query_log';
+----------------+-------+
| Variable_name | Value |
+----------------+-------+
| slow_query_log | OFF |
+----------------+-------+
1 row in set, 1 warning (0.00 sec)
OFF
It means closed, but in actual work, it is better to open for easy optimization.
- The next modified
slow_query_log
value isON
mysql> set global slow_query_log = ON;
Query OK, 0 rows affected (0.01 sec)
Search again slow_query_log
and find that it has been modified ON
, as shown in the following code:
mysql> show variables like 'slow_query_log';
+----------------+-------+
| Variable_name | Value |
+----------------+-------+
| slow_query_log | ON |
+----------------+-------+
1 row in set, 1 warning (0.00 sec)
If we don't add it global
, the modification will report an error:
mysql> set slow_query_log = OFF;
ERROR 1229 (HY000): Variable 'slow_query_log' is a GLOBAL variable and should be set with SET GLOBAL