Змінна статусу MySQL Handler_read_rnd_next значно зростає


11

У статусі MYSQL значення Handler_read_rnd_next дуже високе.

Я знаю, що це значення буде збільшуватися при виконанні запиту, який не має належних індексів.

Але навіть коли ми виконуємо показ шоу типу "Handler_read_rnd_next", це значення збільшується на 2.

На основі цього прапора статусу ми відстежуємо деякі статистичні дані.

Тож кожен раз ця статистика виявляється критичною.

Чи можемо ми виключити ці числа "показ" виконання із числа "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'

Чи є спосіб обмежити це значення чи можу я знати, чому це значення збільшується дуже швидко.


Це насправді викликає проблеми з продуктивністю?
Аарон Браун

На продуктивність не впливає, але інструмент моніторингу перевіряє цей прапор і показує критичне значення.
Фаніндра

Якщо продуктивність не є проблемою, то замість цього зафіксуйте інструмент моніторингу.
Аарон Браун

Я також перевірився з іншими інструментами (Monyog), там же проблема.
Фаніндра

і що? Ігноруйте це, якщо це не спричиняє проблеми з продуктивністю. Це просто лічильник.
Аарон Браун

Відповіді:


5

Перш за все, давайте подивимось на визначення Handler_read_rnd_next.

Відповідно до документації MySQL на Handler_read_rnd_next:

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

А тепер подивіться на ваш запит:

select data from test where data = 'vwx';

Ви сказали, що таблиця має 10 рядів. Як правило, оптимізатор запитів MySQL відхилить використання індексу, якщо кількість рядків, які потрібно перевірити, перевищує 5% від загальної кількості рядків.

Давайте зробимо математику. 5% від 10 рядів - 0,5 ряду. Навіть якщо кількість рядків, щоб знайти ваші дані, дорівнює 1, тобто більше 0,5. Виходячи з цієї меншої кількості рядків і цього правила індексу, який я щойно згадував, MySQL Quiz Optimizer завжди буде виконувати сканування таблиці.

Оскільки стовпець dataсам індексується, замість сканування таблиці, mysql було проведено індексне сканування.

Якщо ви точно знаєте, що тестова таблиця ніколи не зростатиме, ви можете видалити всі індекси та дозволити сканування таблиці. Змінні стану обробника повинні припиняти збільшення.


Привіт, дякую за відповідь. Я спробував видалити індекс і перевірив значення, виконавши запит. Але значення Handler_read_rnd_next збільшується на 18, що збільшується на 7 з індексом. Таблиця, яку я згадав, не є фіксованою. Ось приклад, я вставив ще 70 рядків у таблицю, тому загальна кількість рядків дорівнює 80 і виконала той самий запит із покажчиком на стовпці "дані", який все ще повертає лише один рядок. Але все ж, коли я перевіряю значення "Handler_read_rnd_next", воно все одно збільшується на 7. Чи можу я знати причину того, як цей прапор збільшується і як це обмежити.
Фаніндра

Точно ті самі причини, які я наводив, все ще застосовуються. Здійснено індексне сканування. Цього разу повний індекс не знадобився. Очевидно, що для отримання одного ряду в BTREE індексу необхідно було пройти 7 вузлів листів. Лічильники статусів обробника виявляють використання індексу. Єдиний спосіб обмежитись - це повністю видалити індекс, як я вже заявив. В іншому випадку це завжди очікувана поведінка. Краще індексувати складніші структури таблиць і правильно розроблені запити можуть пом'якшити підрахунок обробників, але ніколи не можуть їх повністю видалити.
RolandoMySQLDBA

"Як правило, оптимізатор запитів MySQL відхиляє використання індексу, якщо кількість рядків, які потрібно перевірити, перевищує 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)

0

Якщо в стовпці "дані" є унікальний / первинний індекс, то ви вже зробили оптимізацію для цього запиту. Я не можу подумати, що щодо цього може бути здійснена додаткова оптимізація.

Також ви можете переконатися, чи було зроблено ПОЛЬНІ СТАНОВІ СКАНИ чи ні?

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

Переконайтесь, що select_scan не збільшив його значення, таким чином ви можете перевірити, чи виконано FULL TABLE SCAN чи ні. Вам слід спробувати оптимізувати запит, який не виконає ПОВНОГО СКАДУВАННЯ ТАБЛИЦІ.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.