MySQL — выявление медленных запросов

Статья для новичков. В MySQL есть встроенное средство для отслеживания медленных запросов.

В конфиге нужно просписать

log_slow_queries = /var/log/mysql/mysql-slow.log
long_query_time = 1


log_slow_queries — это путь к файлу, в который будут писаться медленные запросы.
long_query_time — время в секундах. запросы, которые длятся более 1 секунды попадут в лог.

Примеры из жизни

Запрос из движка DLE выполняется 2 секунды. Обратите внимание на регулярное выражение. WTF????

SELECT COUNT(*) as count
FROM dle_users
WHERE email = '19kikazz@gmail.com'
OR LOWER(name) REGEXP '[[:<:]]d[rг]j[eеё][rг][i1l!][cс][kк][aа][yу][[:>:]]'
OR name = 'drjerick';

Или вот выборка 7 записей из Wordpress растягивается на 3 секунды

SELECT SQL_CALC_FOUND_ROWS  wp_posts.*
FROM wp_posts
LEFT JOIN wp_post2cat ON (wp_posts.ID = wp_post2cat.post_id)
LEFT JOIN wp_categories ON (wp_post2cat.category_id = wp_categories.cat_ID)
WHERE 1=1
AND category_id IN (1)
AND (post_type = 'post' AND (post_status = 'publish'))
GROUP BY wp_posts.ID
ORDER BY post_date DESC
LIMIT 0, 7;

Высокая точность

Как отслеживать запросы 0.3 секунды — ведь это тоже долгие запросы.
Вариант 1. Есть специальные патчи для MySQL. Легко нагуглить.
Вариант 2. Написать свой небольшой профайлер.
Например, если работа с базой сосредоточена в одном месте (классе).
Код максимально упрощен. Тут показан сам принцип.

class DB {
    function select($query) {
        $data = mysql_query($query);
        return $data;
    }
}

то в этом классе можно прописать что-то типа.
class DB {
    function select($query) {
        $start_time = microtime(true);
        $data = mysql_query($query);
        $end_time = microtime(true);
        $result = $end_time - $start_time;
        $fp = fopen('/var/log/mysql/mysql-slow.log', 'a+');
        flock($fp, LOCK_EX);
        fwrite($fp, $result.' - '.$query); // пишем в файл время и сам запрос
        flock($fp, LOCK_UN);
        fclose($fp);
        return $data;
    }
}

Таким образом мы получим что-то типа
0.032432 - SELECT * FROM city WHERE id=4
1.127535 - SELECT * FROM user WHERE id=5 AND activity=1
0.487652 - SELECT * FROM post INNER JOIN comments ON post.id = comments.post_id WHERE post_status = 'publish'

#1

Можно заюзать percona, там можно указывать доли секунды для медленных запросов: http://www.percona.com/doc/percona-server/5.1/diagnostics/slow_extended.html?id=percona-server:features:slow_extended_51&redirect=2#long_query_time

Рустам, 14.01.2012 - 23:53
#2

Дякую за хорошу ідею)
Доповню свою функцію по роботі з БД - http://www.sergunik.name/?p=178

Sergunik, 16.01.2012 - 13:00
#3

совсем новичек в mysql я, поподробнее плз -
"В конфиге нужно просписать" - в каком конфиге, как называется файл с конфигом, где он лежит?

Иван, 3.04.2013 - 10:08
#4

конфиг лежит обычно по адресу /etc/mysql/my.cnf

admin, 3.04.2013 - 10:57
Оставить комментарий