Zmienna statusu MySQL Handler_read_rnd_next bardzo rośnie

11

W stanie MYSQL wartość Handler_read_rnd_next jest bardzo wysoka.

Wiem, że ta wartość zostanie zwiększona, gdy zostanie wykonane zapytanie, które nie ma odpowiednich indeksów.

Ale nawet gdy wykonujemy status show, taki jak „Handler_read_rnd_next”, wartość ta zwiększa się o 2.

W oparciu o tę flagę stanu monitorujemy niektóre statystyki.

Dlatego za każdym razem statystyki są krytyczne.

Czy możemy wykluczyć te liczby wykonania „pokaż” z liczby „Handler_read_rnd_next”.

Jeszcze jeden przykład tego

Istnieje tabela z 10 wierszami, tabela jest indeksowana w kolumnie „dane”, a jeśli wykonamy następujące zapytanie:

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

a jeśli sprawdzimy wartość „Handler_read_rnd_next”, zostanie ona zwiększona o 7.

Poniżej przedstawiono wynik polecenia wyjaśniania dla powyższego zapytania:

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'

Czy jest jakiś sposób na ograniczenie tej wartości lub czy mogę wiedzieć, dlaczego ta wartość jest bardzo szybko zwiększana.

Phanindra
źródło
Czy to faktycznie powoduje problem z wydajnością?
Aaron Brown
Nie ma to wpływu na wydajność, ale narzędzie monitorujące sprawdza tę flagę i wykazuje wartość krytyczną.
Phanindra
Jeśli wydajność nie stanowi problemu, napraw narzędzie monitorujące.
Aaron Brown
Sprawdziłem również za pomocą innych narzędzi (Monyog), jest też ten sam problem.
Phanindra,
Więc co? Zignoruj ​​to, jeśli nie powoduje to problemów z wydajnością. To tylko licznik.
Aaron Brown,

Odpowiedzi:

5

Przede wszystkim spójrzmy na definicję Handler_read_rnd_next.

Według dokumentacji MySQL na Handler_read_rnd_next:

Liczba żądań odczytania następnego wiersza w pliku danych. Ta wartość jest wysoka, jeśli wykonujesz wiele skanów tabeli. Zasadniczo sugeruje to, że tabele nie są odpowiednio indeksowane lub że zapytania nie są zapisywane w celu skorzystania z posiadanych indeksów.

Teraz spójrz na swoje zapytanie:

select data from test where data = 'vwx';

Powiedziałeś, że tabela ma 10 wierszy. Zasadniczo Optymalizator zapytań MySQL odrzuci użycie indeksu, jeśli liczba wierszy, które należy zbadać, jest większa niż 5% całkowitej liczby wierszy.

Zróbmy matematykę. 5% z 10 rzędów to 0,5 wiersza. Nawet jeśli liczba wierszy potrzebnych do zlokalizowania danych wynosi 1, to jest większa niż 0,5. Na podstawie tej niższej liczby wierszy i wspomnianej właśnie reguły indeksu MySQL Query Optimizer zawsze wykona skanowanie tabeli.

Ponieważ sama kolumna datajest indeksowana, zamiast skanowania tabeli wykonano skanowanie mysql.

Jeśli masz pewność, że tabela testowa nigdy nie wzrośnie, możesz usunąć wszystkie indeksy i umożliwić skanowanie tabeli. Zmienne statusu modułu obsługi powinny przestać zwiększać.

RolandoMySQLDBA
źródło
Cześć, dzięki za odpowiedź. Próbowałem, usuwając indeks i sprawdziłem wartość, wykonując zapytanie. Ale wartość Handler_read_rnd_next zwiększa się o 18, a wzrost o 7 z indeksem. Tabela, o której wspomniałem, nie jest ustalona. To jest przykład: wstawiłem jeszcze 70 wierszy do tabeli, więc suma wierszy wynosi 80 i wykonałem to samo zapytanie z indeksem na kolumnie „dane”, która wciąż zwraca tylko jeden wiersz. Ale wciąż, gdy sprawdzam wartość „Handler_read_rnd_next”, wciąż rośnie o 7. Czy mogę poznać powód, dla którego ta flaga jest zwiększana i jak to ograniczyć.
Phanindra
Dokładnie te same powody, które podałem, nadal obowiązują. Wykonano skanowanie indeksu. Tym razem pełny indeks nie był potrzebny. Najwyraźniej 7 węzłów liści w BTREE indeksu musiało zostać przemierzonych, aby uzyskać jeden wiersz. Liczniki statusu modułu obsługi ujawniają użycie indeksu. Jedynym sposobem ograniczenia jest całkowite usunięcie indeksu, jak już powiedziałem. W przeciwnym razie jest to zawsze oczekiwane zachowanie. Lepsze indeksowanie bardziej złożonych struktur tabel i odpowiednio zaprojektowane zapytania mogą złagodzić liczenie modułów obsługi, ale nigdy nie mogą ich całkowicie usunąć.
RolandoMySQLDBA
„Zasadniczo Optymalizator zapytań MySQL odrzuci użycie indeksu, jeśli liczba wierszy, które należy zbadać, jest większa niż 5% całkowitej liczby wierszy”. - jest to bardzo, bardzo pomocne, aby wiedzieć. Czy istnieje jakaś oficjalna dokumentacja, która to potwierdza? Dziękuję bardzo!
itoctopus
2

Jaka wersja MySQL?

Powody, dla których ta flaga jest zwiększana, najlepiej udokumentować tutaj: http://www.mysqlperformanceblog.com/2010/06/15/what-does-handler_read_rnd-mean/

Krótko mówiąc, jest to tylko licznik liczby wierszy pobranych w kolejności podczas pełnego lub częściowego skanowania tabeli.

To powiedziawszy, otrzymuję inny wynik:

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
źródło
0

Jeśli w kolumnie „Dane” znajduje się indeks unikatowy / podstawowy, oznacza to, że już wykonałeś optymalizację dla tego zapytania. Nie sądzę, że można na tym dokonać dalszej optymalizacji.

Możesz także sprawdzić, czy wykonano PEŁNE SKANOWANIE TABELI, czy nie?

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

Upewnij się, że select_scan nie zwiększył swojej wartości, w ten sposób możesz sprawdzić, czy PEŁNE SKANOWANIE TABELI zostało wykonane, czy nie. Powinieneś spróbować zoptymalizować zapytanie, które nie wykona PEŁNEGO SKANOWANIA TABELI.

Mahesh Patil
źródło