Тестирование производительности запросов в mysql - PullRequest
24 голосов
/ 03 мая 2010

Я пытаюсь настроить скрипт, который бы тестировал производительность запросов на сервере разработки mysql. Вот более подробная информация:

  • У меня есть root-доступ
  • Я единственный пользователь, который обращается к серверу
  • В основном заинтересованы в производительности InnoDB
  • Оптимизируемые мной запросы - это в основном поисковые запросы (SELECT ... LIKE '%xy%')

Я хочу создать надежную среду тестирования для измерения скорости одного запроса, не зависящую от других переменных.

До сих пор я использовал SQL_NO_CACHE , но иногда результаты таких тестов также показывают поведение кэширования - выполнение намного дольше при первом запуске и меньше времени при последующих запусках.

Если кто-то может объяснить это поведение во всех деталях, я мог бы использовать SQL_NO_CACHE; Я полагаю, что это может быть связано с кэшированием файловой системы и / или кэшированием индексов, используемых для выполнения запроса, как объясняется в этом посте. Мне неясно, когда буферный пул и ключевой буфер станут недействительными или как они могут помешать тестированию.

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

Ответы [ 6 ]

63 голосов
/ 06 мая 2010

Предполагая, что вы не можете оптимизировать саму операцию LIKE, вы должны попытаться оптимизировать базовый запрос без минимизации количества проверяемых строк.

Некоторые вещи, которые могут быть полезны для этого:

rows столбец в EXPLAIN SELECT ... результат. Тогда

mysql> set profiling=1;
mysql> select sql_no_cache * from mytable;
 ...
mysql> show profile;
+--------------------+----------+
| Status             | Duration |
+--------------------+----------+
| starting           | 0.000063 |
| Opening tables     | 0.000009 |
| System lock        | 0.000002 |
| Table lock         | 0.000005 |
| init               | 0.000012 |
| optimizing         | 0.000002 |
| statistics         | 0.000007 |
| preparing          | 0.000005 |
| executing          | 0.000001 |
| Sending data       | 0.001309 |
| end                | 0.000003 |
| query end          | 0.000001 |
| freeing items      | 0.000016 |
| logging slow query | 0.000001 |
| cleaning up        | 0.000001 |
+--------------------+----------+
15 rows in set (0.00 sec)

Тогда

mysql> FLUSH STATUS;
mysql> select sql_no_cache * from mytable;
...
mysql> SHOW SESSION STATUS LIKE 'Select%';
+------------------------+-------+
| Variable_name          | Value |
+------------------------+-------+
| Select_full_join       | 0     |
| Select_full_range_join | 0     |
| Select_range           | 0     |
| Select_range_check     | 0     |
| Select_scan            | 1     |
+------------------------+-------+
5 rows in set (0.00 sec)

И еще одно интересное значение - last_query_cost, которое показывает, насколько дорогой оптимизатор оценил запрос (значение равно числу случайных чтений страницы):

mysql> SHOW STATUS LIKE 'last_query_cost';
+-----------------+-------------+
| Variable_name   | Value       |
+-----------------+-------------+
| Last_query_cost | 2635.399000 |
+-----------------+-------------+
1 row in set (0.00 sec)

Документация MySQL - ваш друг.

2 голосов
/ 07 мая 2010

Цитируется с этой страницы : Параметры SQL_NO_CACHE влияют на кэширование результатов запроса в кеше запроса . Если ваша таблица довольно мала, возможно, сама таблица уже кэширована. Так как вы просто избегаете кеширования результатов, а не таблиц, вы иногда получаете описанное поведение. Итак, как сказано в других публикациях, вы должны очищать ваши таблицы между запросами.

1 голос
/ 06 мая 2010

Рассматривали ли вы использование Maatkit ? Одна из его возможностей, с которыми я немного знаком, - это захват сетевых данных MySQL с помощью tcpdump и обработка дампа с помощью mk-query-digest. Этот инструмент позволяет вам показать некоторые мелкие детали о каждом запросе. Но есть целый ряд других инструментов, которые должны упростить анализ запросов.

1 голос
/ 05 мая 2010

Как предполагает связанная статья, используйте FLUSH TABLES между тестовыми прогонами, чтобы сбросить как можно больше (особенно кеш запросов).

Не должно ли ваше тестирование принять во внимание, что InnoDB сам будет иметь различные состояния во время фактической производительности, так что вы заинтересовались совокупной производительностью в течение нескольких испытаний? Насколько «реальным» будет ваше тестирование производительности, если вы хотите сбросить InnoDB для каждого испытания? Запрос, который вы отклоняете из-за плохой работы сразу после перезапуска, может оказаться самым лучшим запросом после небольшого прогрева InnoDB.

На вашем месте я бы сосредоточился на том, что оптимизатор запросов делает отдельно от производительности InnoDB. Там много написано о том, как настроить InnoDB, но это помогает иметь хорошие запросы для запуска.

Вы также можете попробовать измерить производительность с помощью эквивалентных таблиц MyISAM, где FLUSH TABLES действительно вернет вас к практически идентичной начальной точке.

Вы пытались вообще отключить кэширование запросов? Даже с SQL_NO_CACHE штраф составляет около 3%, если кеш запросов включен.

0 голосов
/ 06 мая 2010

Полнотекстовые запросы в InnoDB медленные (как операторы «% query%»), вы ничего не можете сделать для их оптимизации. Решения варьируются от передачи конкретной таблицы, которую вы запрашиваете, в MyISAM, чтобы вы могли создавать полнотекстовые индексы (которую innoDB не поддерживает), до денормализации строки в индексы с возможностью поиска (не рекомендуется), Doctrine ORM представляет собой простой пример того, как архивировать это: http://www.doctrine -project.org / документация / ручной / 1_1 / нл / поведение: основные-поведения: поиск «Правильным» решением вашей проблемы было бы проиндексировать информацию, на которой вы используете полнотекстовый поиск, с помощью решения, такого как Sphinx Search или Apache Solr.

Как уже говорилось ранее, при сравнении результатов необходимо учитывать состояние кэша. Заполненный кэш дает чрезвычайно производительные запросы. Следует учитывать процент попаданий в кеш определенного запроса, даже если это дорогостоящий запрос, если он имеет коэффициент попадания в кэш 99%, средняя производительность будет очень высокой.

Тонкая настройка запросов не является «серебряной пулей», возможно, вы добавляете сложность своему приложению ради оптимизаций, которые в целом в производственной среде незначительны.

Учитывайте вашу рабочую нагрузку, устраняйте частые, не выполняющиеся запросы (используйте slow_query_log в mysql, не начинайте слепо оптимизировать запросы).

0 голосов
/ 05 мая 2010

Вы можете попробовать инструмент MySQL, я думал, что у него есть монитор операторов SQL, чтобы вы могли видеть, как быстро и почему он быстрый

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...