MySQL慢查询查找和调优测试
程序员文章站
2023-12-22 16:15:46
编辑 my.cnf或者my.ini文件,去除下面这几行代码的注释: 复制代码 代码如下: log_slow_queries = /var/log/mysql/mysql-s...
编辑 my.cnf或者my.ini文件,去除下面这几行代码的注释:
log_slow_queries = /var/log/mysql/mysql-slow.log
long_query_time = 2
log-queries-not-using-indexes
这将使得慢查询和没有使用索引的查询被记录下来。
这样做之后,对mysql-slow.log文件执行tail -f命令,将能看到其中记录的慢查询和未使用索引的查询。
随便提取一个慢查询,执行explain:
explain low_query
你将看到下面的结果:
+----+-------------+---------------------+------+---------------+------+---------+------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | extra |
+----+-------------+---------------------+------+---------------+------+---------+------+------+-------------+
| 1 | simple | some_table | all | null | null | null | null | 166 | using where |
+----+-------------+---------------------+------+---------------+------+---------+------+------+-------------+
注意上面的rows和key列。rows显示该查询影响了多少行记录,我们不想让这个值太大。key显示用了哪个索引,为null时表示查询未用任何索引。
如果想让查询更快,你或许需要为某些列增加索引:
create index myapp_mytable_myfield_idx on myapp_mytable(myfield);
除了配置mysql配置文件来实现记录慢查询外,还有下面的方法可以记录慢查询:
select t.table_schema as `db`,
t.table_name as `table`,
s.index_name as `index name`,
s.column_name as `field name`,
s.seq_in_index `seq in index`,
s2.max_columns as `# cols`,
s.cardinality as `card`,
t.table_rows as `est rows`,
round(((s.cardinality / ifnull(t.table_rows, 0.01)) * 100), 2) as `sel %`
from information_schema.statistics s
inner join information_schema.tables t on s.table_schema = t.table_schema and s.table_name = t.table_name
inner join (
select table_schema, table_name, index_name, max(seq_in_index) as max_columns
from information_schema.statistics
where table_schema != 'mysql' group by table_schema, table_name, index_name ) as s2 on s.table_schema = s2.table_schema and s.table_name = s2.table_name and s.index_name = s2.index_name
where t.table_schema != 'mysql' /* filter out the mysql system db */
and t.table_rows > 10 /* only tables with some rows */
and s.cardinality is not null /* need at least one non-null value in the field */
and (s.cardinality / ifnull(t.table_rows, 0.01)) < 1.00 /* unique indexes are perfect anyway */
order by `sel %`, s.table_schema, s.table_name /* desc for best non-unique indexes */
limit 10;
复制代码 代码如下:
log_slow_queries = /var/log/mysql/mysql-slow.log
long_query_time = 2
log-queries-not-using-indexes
这将使得慢查询和没有使用索引的查询被记录下来。
这样做之后,对mysql-slow.log文件执行tail -f命令,将能看到其中记录的慢查询和未使用索引的查询。
随便提取一个慢查询,执行explain:
复制代码 代码如下:
explain low_query
你将看到下面的结果:
+----+-------------+---------------------+------+---------------+------+---------+------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | extra |
+----+-------------+---------------------+------+---------------+------+---------+------+------+-------------+
| 1 | simple | some_table | all | null | null | null | null | 166 | using where |
+----+-------------+---------------------+------+---------------+------+---------+------+------+-------------+
注意上面的rows和key列。rows显示该查询影响了多少行记录,我们不想让这个值太大。key显示用了哪个索引,为null时表示查询未用任何索引。
如果想让查询更快,你或许需要为某些列增加索引:
create index myapp_mytable_myfield_idx on myapp_mytable(myfield);
除了配置mysql配置文件来实现记录慢查询外,还有下面的方法可以记录慢查询:
复制代码 代码如下:
select t.table_schema as `db`,
t.table_name as `table`,
s.index_name as `index name`,
s.column_name as `field name`,
s.seq_in_index `seq in index`,
s2.max_columns as `# cols`,
s.cardinality as `card`,
t.table_rows as `est rows`,
round(((s.cardinality / ifnull(t.table_rows, 0.01)) * 100), 2) as `sel %`
from information_schema.statistics s
inner join information_schema.tables t on s.table_schema = t.table_schema and s.table_name = t.table_name
inner join (
select table_schema, table_name, index_name, max(seq_in_index) as max_columns
from information_schema.statistics
where table_schema != 'mysql' group by table_schema, table_name, index_name ) as s2 on s.table_schema = s2.table_schema and s.table_name = s2.table_name and s.index_name = s2.index_name
where t.table_schema != 'mysql' /* filter out the mysql system db */
and t.table_rows > 10 /* only tables with some rows */
and s.cardinality is not null /* need at least one non-null value in the field */
and (s.cardinality / ifnull(t.table_rows, 0.01)) < 1.00 /* unique indexes are perfect anyway */
order by `sel %`, s.table_schema, s.table_name /* desc for best non-unique indexes */
limit 10;