Можно ли как-нибудь узнать, какие запросы к какой таблице производились на протяжении работы веб-приложения? И сколько времени они занимали?

Здравствуйте! Читаю статью на хабре Оптимизация работы с MySQL. Там сказано:
Выбор индексов должен начинаться с анализа всех запросов к данной таблице. Очень часто после такого анализа вместо трех-четырех индексов можно сделать один составной.

Неужели нужно в коде всего приложения искать все запросы к определенной таблице и анализировать их? Может, можно как-нибудь в MySQL это вывести? Какие запросы были к какой таблице и сколько времени они занимали? Сравнить эти запросы - какие чаще, какие реже. Какие занимали много мс, какие мало. Можно так?
  • Вопрос задан
  • 1573 просмотра
Решения вопроса 1
Rsa97
@Rsa97
Для правильного вопроса надо знать половину ответа
Обычно анализ начинают с включения журнала медленных запросов (slow query log). Туда записываются все запросы, анализирующие больше заданного количества строк и занимающие больше заданного времени.
Если этого не хватает, то можно включить общий журнал запросов (general query log). Туда уже попадают все запросы и информация о подключении/отключении клиентов.
Ответ написан
Пригласить эксперта
Ответы на вопрос 3
landergate
@landergate
IT-шный jack-of-all-trades
  1. В my.cnf:
    performance_schema=1
  2. Перезапустить MySQL.
  3. Импортировать sys_xx.sql из проекта mysql-sys: https://github.com/mysql/mysql-sys
  4. Подождать немного времени, пока наберётся статистика с последнего старта БД.
  5. Анализировать запросы в таблице `sys`.`statement_analysis`.
Ответ написан
@heahoh
Full stackoverflow developer
Над прослойкой драйвера к вашей бд вы можете написать обертку и вместо вызова, к примеру, PDO::query вызывать PDOExtend::query с наполнением вида:
class PDOExtend extends PDO
{
    /** @var \Psr\Log\LoggerInterface */
    protected $logger;

    public function __construct(string $dsn, string $username, string $passwd, array $options, \Psr\Log\LoggerInterface $logger)
    {
        parent::__construct($dsn, $username, $passwd, $options);
        $this->logger = $logger;
    }

    public function query(string $preparedQuery): PDOStatement
    {
        $queryStart = microtime(true);
        $result = parent::query($preparedQuery);
        $queryStop = microtime(true);

        $this->logger->debug(sprintf('%s query executed %s', static::class, $preparedQuery), [
            'query_start_time'      => $queryStart,
            'query_finish_time'     => $queryStop,
            'elapsed'               => $queryStop - $queryStart
        ]);
        
        return $result;
    }
}
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через TM ID
Похожие вопросы