Identifying MySQL slow queries
One of the most important steps in optimizing and tuning mysql is to identify the queries that are causing problems. How can we find out what queries are taking a long time to complete? How can we see what queries are slowing down the mysql server? Mysql has the answer for us and we only need to know where to look for it…
Normally from my experience if we take the most ‘expensive’ 10 queries and we optimize them properly (maybe running them more efficiently, or maybe they are just missing a simple index to perform properly), then we will immediately see the result on the overall mysql performance. Then we can iterate this process and optimize the new top 10 queries. This article shows how to identify those ’slow’ queries that need special attention and proper optimization.
1. Activate the logging of mysql slow queries.
The first step is to make sure that the mysql server will log ’slow’ queries and to properly configure what we are considering as a slow query.
First let’s check on the mysql server if we have slow query logging enabled:
mysqladmin var |grep log_slow_queries
| log_slow_queries | OFF |If log_slow_queries is ON then we already have it enabled. This setting is by default disabled – meaning that if you don’t have log_slow_queries defined in the mysql server config this will be disabled.
The mysql variable long_query_time (default 1) defines what is considered as a slow query. In the default case, any query that takes more than 1 second will be considered a slow query.
Ok, now for the scope of this article we will enable the mysql slow query log. In order to do to do this in your mysql server config file (/etc/my.cnf RHEL/Centos or /etc/mysql/my.cnf on Debian, etc.) in the mysqld section we will add:
[mysqld]
long_query_time = 1
log-slow-queries = /var/log/mysql/mysql-slow.logThis configuration will log all queries that take more than 1 sec in the file /var/log/mysql/mysql-slow.log. You will probably want to define these based on your particular setup (maybe you will want the logs in a different location and/or you will consider a higher value than 1 sec to be slow query).
Once you have done the proper configurations to enable mysql to log slow queries you will have to reload the mysql service in order to activate the changes.
2. Investigate the mysql slow queries log.
After we enabled slow query logging we can look inside the log file for each slow query that was executed by the server. Various details are logged to help us understand how was the query executed:
- Time: how long it took to execute the query
- Lock: how long was a lock required
- Rows: how many rows were investigated by the query (this can help see quickly queries without indexes)
- Host: the actual host that launched the query (this can be localhost, or a different one in multiple servers setup)
- The actual mysql query.
This information allows us to see what queries need to be optimized, but on a high traffic server and with lots of slow queries this log can grow up very fast making it very difficult to find any relevant information inside it.
In this case we have two choices:
- We increase the long_query_time and we focus on the queries that take the most time to complete, and we gradually decrease this once we solve the queries.
- We use some sort of tool to parse the slow query log file and have it show us the most used queries.
Of course based on the particular setup we might end up using both methods.
MySQL gives us a small tool that does exactly this: mysqldumpslow. This parses and summarizes the MySQL slow query log.
From the manual page here are the options we can use:
-v verbose
-d debug
-s=WORD
what to sort by (t, at, l, al, r, ar etc)
-r reverse the sort order (largest last instead of first)
-t=NUMBER
just show the top n queries
-a don't abstract all numbers to N and strings to 'S'
-n=NUMBER
abstract numbers with at least n digits within names
-g=WORD
grep: only consider stmts that include this string
-h=WORD
hostname of db server for *-slow.log filename (can be wildcard)
-i=WORD
name of server instance (if using mysql.server startup script)
-l don't subtract lock time from total timeFor example using:
mysqldumpslow -s c -t 10we get the top 10 queries (-t 10) sorted by the number of occurrences in the log (-s c).
Now it is time to have those queries optimized. This is outside of the scope of this article but the next logical step is to run EXPLAIN on the mysql query and then, based on the particular query to take the appropriate actions to fix it.
>
Tags: mysql







21st November 2006, 15:42
Identifying MySQL slow queries…
Here are some handy on monitoring troublesome queries in your MySQL db. With the info identified here you will setup slowquery logging and be able to generate short reports of the top ten……
28th November 2006, 10:06
[...] Identifying MySQL slow queries | MDLog:/sysadmin … steps in optimizing and tuning mysql is to identify the queries that are causing problems. How can we find out what queries are taking a long time to complete? How can we see what queries are slowing down the mysql server? Mysql has the answer for us and we only need to know where to look for it… [...]
28th November 2006, 16:35
Do I need to create the directory mysql? And do I need to create an empty file named mysql-slow.log? Or will MySQL make these when it encounters the first slow query?
28th November 2006, 16:45
John,
you can place the log file anywhere you want it… The folder where you place it needs to exist and mysql daemon must have permissions to write to that folder. The file is automatically created by mysql.
30th November 2006, 08:56
Optimizando las consultas en Mysql…
En este artÃculo nos explican como detectar consultas lentas en MySQL…pudiendo asi optimizar nuestras aplicaciones. (Muy interesante pero en inglés)…
30th November 2006, 09:02
[...] Identifica consultas lentas en MySQL [...]
30th November 2006, 10:17
[...] Via Menéame trobo un post força interessant sobre la detecció de queries MySQL costoses. [...]
5th March 2007, 10:41
Hello I am getting the following error when i run, mysqldumpslow
====
root@server145 [~]# mysqldumpslow -s c -t 10
Can’t determine basedir from ‘my_print_defaults mysqld’ output: –query_cache_limit=1M
–query_cache_size=16M
–query_cache_type=1
–skip_networking
.
.
====
Mysql version is 4.1.21-standard-log
Could you please explain how should i solve this.
Thank You
5th March 2007, 14:21
Neo,
Try to define in your my.cnf the proper location of “basedir”, for ex:
basedir = /usr/
and see if this solves your issue.
6th March 2007, 00:09
Hello Marius . . I tried “basedir = /usr/ and basedir = /var/lib”. None seems not working. Could you please help me to sort this out. Thank You . . Neo
6th March 2007, 00:13
Neo,
Do you still get the same error? What OS are you running? Is the mysql installation bundled from the OS, or manual (or compiled) from mysql.com?
6th March 2007, 02:14
Hello Marius,
Thanks for supporting me to solve the issue. Please see the following details,
—-
root@server145 [~]# cat /etc/redhat-release
Red Hat Linux release 9 (Shrike)
—-
root@server145 [~]# cat /etc/my.cnf
[mysqld]
query_cache_limit=1M
query_cache_size=16M
query_cache_type=1
skip_networking
##its a heavy traffic server
max_connections=1000
wait_timeout=7200
connect_timeout=10
key_buffer=16M
join_buffer=1M
table_cache=1024
sort_buffer_size=2M
read_buffer_size=1M
old-passwords = 1
safe-show-database
tmp_table_size = 32M
max_allowed_packet = 16M
max_connect_errors = 10
long_query_time = 1
log-slow-queries = /var/log/mysql/mysql-slow.log
basedir = /usr/
—–
root@server145 [~]# mysql
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 31760 to server version: 4.1.21-standard-log
—–
Databases are in /var/lib/mysql/
I tried googling. But no use. I found a lot of people reprting this error. But none of them get the solution ..
Hope we can help them …
Thanks
Regards
Neo
7th March 2007, 00:26
Neo,
It’s definitely not easy to debug things like this (gives a new meaning to the word remote), but I will try to help you out.
So what is the error you get with this my.cnf?
Can you paste also the output of the command:
my_print_defaults mysqld
11th March 2007, 19:13
Hi Marius,
I am sorry for replying lately …
This is the output ….
root@ertd [/usr/local/apache/htdocs/mrtg]# mysqldumpslow -s c -t 10
Can’t determine basedir from ‘my_print_defaults mysqld’ output: –skip-locking
–max_connections=300
–max_user_connections=10
–connect_timeout=15
–key_buffer=16M
–join_buffer=1M
–record_buffer=1M
–sort_buffer=2M
–table_cache=1028
–thread_cache_size=286
–max_allowed_packet=5M
–wait_timeout=15
–query_cache_limit=1M
–query_cache_size=64M
–query_cache_type=1
–thread_concurrency=3
–long_query_time=1
–log-slow-queries=/var/lib/mysql/mysql.slow
11th March 2007, 20:15
Hello Marius,
I have figured out the error …
Adding these two more parameters to my.cnf will solve the issue
basedir=/var/lib/mysql
datadir=/var/lib/mysql
—-
Thanks a lot for providing a lot of useful and wonderful tutorials on cpanel and linux … Your postings are really helping me out in times of difficulties … Please post more topics on CPANEL/WHM ..
Thanks again
Neo
13th March 2007, 02:37
Hi Neo,
I am happy this is working for you now!
.
Regrads,
- Marius -
30th March 2007, 19:15
Neo, I have the same problem, where exactly in the my.cnf did you add these entries. I have the basedir parameter under mysql.server, I’ve tried adding it to the mysqld section but then mysqld won’t start. I have the datadir parameter in the mysqld section.
Thanks!
David
19th April 2007, 12:24
Hi!
For those having problems with mysqldumpslow: try using it in this manner: mysqldumpslow -s t /var/lib/mysql/HOSTNAME-slow.log
Thanks.
19th July 2007, 03:26
Yeah if you go in this directory by “cd /var/lib/mysql/” and use “ls” it will show you what the name is of your slow queries log.
Then you can use something like
mysqldumpslow -s t /var/lib/mysql/HOSTNAME-slow.log
6th December 2007, 16:03
[...] Identifying slow db queries is critical for the optimal operation of the db server. There is an excellent guide that helps to accomplish this task: http://www.ducea.com/2006/11/06/identifying-mysql-slow-queries/ [...]
17th January 2008, 22:55
[...] out the following link: Identifying MySQL slow queries | MDLog:/sysadmin [...]
7th April 2008, 21:24
[...] información aquà y mucha más en la documentación oficial de MySQL. blog de pedro [...]
10th May 2008, 00:44
[...] Identifying MySQL slow queries | MDLog:/sysadmin Here are some handy on monitoring troublesome queries in your MySQL db. With the info identified here you will setup slowquery logging and be able to generate short reports of the top ten slowest queries(queries that takes longer than 1 second to execute) (tags: database howto lamp linux sysadmin optimization performance mysql tuning tutorial) [...]
21st August 2008, 01:13
The correct way to solve this is to put basedir=/usr under the [mysqld] section.
13th February 2009, 10:41
[...] Identifying MySQL slow queries [...]
25th June 2009, 11:16
Hi ,
While running the “mysqldumpslow” command i am getting the following error:
$ mysqldumpslow -s c -t 10
Can’t find ‘/mnt/data/mysql//*-slow.log’
here is what i got from $ my_print_defaults mysqld
–user=mysql
–pid-file=/var/run/mysqld/mysqld.pid
–socket=/var/run/mysqld/mysqld.sock
–port=3306
–basedir=/usr
–datadir=/mnt/data/mysql/
–tmpdir=/tmp
–language=/usr/share/mysql/english
–skip-external-locking
–bind-address=127.0.0.1
–key_buffer=16M
–max_allowed_packet=16M
–thread_stack=128K
–thread_cache_size=8
–query_cache_limit=1M
–query_cache_size=16M
–log_slow_queries=/var/log/mysql/mysql-slow.log
–long_query_time=2
–log-queries-not-using-indexes
–skip-bdb
–old_passwords=false.
any help will be highly appreciated
25th June 2009, 17:18
@killerBird: not sure why this is happening for your system. You can try to add the logfile to the command line like this:
25th June 2009, 22:53
@Marius:my mistake ! permission issues . its alright now ..
but thanks for this advice, now i can run a bash script with your command to get the log file at a specific interval. your article is indeed very helpful. Thanks a lot.
M little confused with the log file syntax , need to know what that count, time, lock, rows means .
23rd July 2009, 10:34
can’t find mysqldumpslow, im using easyphp 2.0 on windows xp. what can i do to get it?
2nd February 2010, 00:08
Thanks for this article -it’s helping me debug some serious DB slow downs we’re getting at the moment. I too had the same problem as @neo. I corrected it by using the following command (specifying the path and slow log file):
mysqldumpslow -s t /var/log/mysql-slow.log