Переменная состояния MySQL Handler_read_rnd_next сильно растет

11

В состоянии MYSQL значение Handler_read_rnd_next очень высокое.

Мне известно, что это значение будет увеличиваться при выполнении запроса, который не имеет надлежащих индексов.

Но даже когда мы выполняем шоу-статус, такой как 'Handler_read_rnd_next', это значение увеличивается на 2.

Основываясь на этом флаге состояния, мы отслеживаем некоторые статистические данные.

Так что каждый раз эта статистика показывает критическую.

Можем ли мы исключить эти подсчеты выполнения 'show' из подсчета 'Handler_read_rnd_next'.

Еще один пример для этого,

Есть таблица с 10 строками, таблица индексируется по столбцу «данные», и если мы выполним следующий запрос:

select data from test where data = 'vwx' -> returns one row

и если мы проверим значение Handler_read_rnd_next, оно будет увеличено на 7.

Ниже приведен результат команды объяснения для вышеуказанного запроса:

explain select data from test where data = 'vwx';

id, select_type, table, type, possible_keys, key, key_len, ref, rows, Extra

1, 'SIMPLE', 'test', 'ref', 'data', 'data', '35', 'const', 1, 'Using where; Using index'

Есть ли способ ограничить это значение, или я могу знать, почему это значение очень быстро увеличивается.

Phanindra
источник
Это на самом деле вызывает проблемы с производительностью?
Аарон Браун
Никакая производительность не пострадает, но инструмент мониторинга проверяет этот флаг и показывает критическое.
Фаниндра
Если производительность не является проблемой, вместо этого исправьте инструмент мониторинга.
Аарон Браун
Я проверил и другие инструменты (Monyog), там тоже проблема.
Фаниндра
Ну и что? Игнорируйте это, если это не вызывает проблемы с производительностью. Это просто счетчик.
Аарон Браун

Ответы:

5

Прежде всего, давайте посмотрим на определение Handler_read_rnd_next.

Согласно документации MySQL на Handler_read_rnd_next:

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

Теперь посмотрите на ваш запрос:

select data from test where data = 'vwx';

Вы сказали, что в таблице 10 строк. Как показывает практика, MySQL Query Optimizer не будет использовать индекс, если число строк, которое необходимо изучить, превышает 5% от общего числа строк.

Давайте посчитаем. 5% из 10 строк - это 0,5 строки. Даже если количество строк, необходимых для поиска ваших данных, равно 1, это больше, чем 0,5. На основании этого меньшего числа строк и правила индекса, которое я только что упомянул, MySQL Query Optimizer всегда будет выполнять сканирование таблицы.

Поскольку сам столбец dataиндексируется, вместо сканирования таблицы mysql выполнял сканирование индекса.

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

RolandoMySQLDBA
источник
Привет, спасибо за ответ. Я попытался удалить индекс и проверил значение, выполнив запрос. Но значение Handler_read_rnd_next увеличивается на 18, что увеличивается на 7 с индексом. Таблица, которую я упомянул, не является фиксированной. Это пример, я вставил еще 70 строк в таблицу, поэтому общее количество строк равно 80 и выполнил тот же запрос с индексом для столбца «данные», который по-прежнему возвращает только одну строку. Но все же, когда я проверяю значение Handler_read_rnd_next, оно все еще увеличивается на 7. Могу ли я узнать причину, по которой этот флаг увеличивается, и как это ограничить.
Фаниндра
Те же самые причины, которые я привел, все еще применяются. Сканирование индекса было выполнено. На этот раз полный индекс не понадобился. Очевидно, 7 листовых узлов в BTREE индекса пришлось пройти через одну строку. Счетчики состояния обработчика показывают использование индекса. Единственный способ ограничить это удалить индекс, как я уже сказал. В противном случае, это всегда ожидаемое поведение. Лучшее индексирование более сложных табличных структур и правильно спроектированных запросов может уменьшить количество обработчиков, но никогда не сможет полностью их удалить.
RolandoMySQLDBA
«Как правило, MySQL Query Optimizer отклоняет использование индекса, если количество строк, которое необходимо изучить, превышает 5% от общего количества строк». - это очень и очень полезно знать. Есть ли официальная документация, подтверждающая это? Огромное спасибо!
итопоп
2

Какая версия MySQL?

Причины, по которым этот флаг увеличивается, лучше всего задокументировать здесь: http://www.mysqlperformanceblog.com/2010/06/15/what-does-handler_read_rnd-mean/

Короче говоря, это просто счетчик количества строк, выбранных по порядку во время полного или частичного сканирования таблицы.

Теперь, что сказал, я получаю другой результат:

mysql> CREATE TABLE `test` (
    ->   `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
    ->   `data` varchar(255) NOT NULL,
    ->   PRIMARY KEY (`id`),
    ->   KEY `data` (`data`)
    -> ) ENGINE=InnoDB;
Query OK, 0 rows affected (0.27 sec)

mysql> INSERT INTO test (data) VALUES ('a'), ('b'), ('c'), ('d'), ('e'), ('f'), ('g'), ('h'), ('i'), ('vwx');
Query OK, 10 rows affected (0.06 sec)
Records: 10  Duplicates: 0  Warnings: 0

mysql> FLUSH STATUS;
Query OK, 0 rows affected (0.07 sec)

mysql> select data from test where data = 'vwx';
+------+
| data |
+------+
| vwx  |
+------+
1 row in set (0.04 sec)

mysql> SHOW SESSION STATUS LIKE 'Handler%';
+----------------------------+-------+
| Variable_name              | Value |
+----------------------------+-------+
| Handler_commit             | 1     |
| Handler_delete             | 0     |
| Handler_discover           | 0     |
| Handler_prepare            | 0     |
| Handler_read_first         | 0     |
| Handler_read_key           | 3     |
| Handler_read_last          | 0     |
| Handler_read_next          | 1     |
| Handler_read_prev          | 0     |
| Handler_read_rnd           | 0     |
| Handler_read_rnd_next      | 0     |
| Handler_rollback           | 0     |
| Handler_savepoint          | 0     |
| Handler_savepoint_rollback | 0     |
| Handler_update             | 0     |
| Handler_write              | 0     |
+----------------------------+-------+
16 rows in set (0.15 sec)
RS
источник
0

Если в столбце «data» имеется уникальный / первичный индекс, то вы уже выполнили оптимизацию для этого запроса. Я не могу думать, что дальнейшая оптимизация может быть сделана на этом.

Также вы можете проверить, был ли выполнен FULL TABLE SCAN или нет?

SHOW STATUS like 'select_scan'; 
SELECT data from test where data='vmx';
SHOW STATUS like 'select_scan'; 

Убедитесь, что select_scan не увеличил свое значение. Таким образом, вы можете проверить, выполняется ли FULL TABLE SCAN или нет. Вы должны попытаться оптимизировать запрос, который не будет выполнять FULL TABLE SCAN.

Махеш Патил
источник