Die MySQL-Statusvariable Handler_read_rnd_next wächst stark

11

Im MYSQL-Status ist der Wert für Handler_read_rnd_next sehr hoch.

Mir ist bekannt, dass dieser Wert erhöht wird, wenn eine Abfrage ausgeführt wird, die keine richtigen Indizes hat.

Aber selbst wenn wir den Show-Status wie 'Handler_read_rnd_next' ausführen, wird dieser Wert um 2 erhöht.

Basierend auf diesem Statusflag überwachen wir einige Statistiken.

Diese Statistiken werden also jedes Mal kritisch angezeigt.

Können wir diese 'show'-Ausführungszählungen von der' Handler_read_rnd_next'-Zählung ausschließen?

Ein weiteres Beispiel dafür:

Es gibt eine Tabelle mit 10 Zeilen, die Tabelle ist in der Spalte 'Daten' indiziert, und wenn wir die folgende Abfrage ausführen:

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

und wenn wir den Wert von 'Handler_read_rnd_next' überprüfen, wurde er um 7 erhöht.

Das folgende Ergebnis ist der Befehl EXPLAIN für die obige Abfrage:

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'

Gibt es eine Möglichkeit, diesen Wert einzuschränken, oder kann ich wissen, warum dieser Wert sehr schnell erhöht wird?

Phanindra
quelle
Verursacht dies tatsächlich ein Leistungsproblem?
Aaron Brown
Keine Leistung wird beeinträchtigt, aber das Überwachungstool überprüft dieses Flag und zeigt es kritisch an.
Phanindra
Wenn die Leistung kein Problem darstellt, beheben Sie stattdessen das Überwachungstool.
Aaron Brown
Ich hatte auch mit anderen Tools (Monyog) nachgefragt, da auch das gleiche Problem.
Phanindra
Na und? Ignorieren Sie es, wenn es kein Leistungsproblem verursacht. Es ist nur ein Zähler.
Aaron Brown

Antworten:

5

Schauen wir uns zunächst die Definition von Handler_read_rnd_next an.

Gemäß der MySQL-Dokumentation zu Handler_read_rnd_next:

Die Anzahl der Anforderungen zum Lesen der nächsten Zeile in der Datendatei. Dieser Wert ist hoch, wenn Sie viele Tabellenscans durchführen. Im Allgemeinen deutet dies darauf hin, dass Ihre Tabellen nicht ordnungsgemäß indiziert sind oder dass Ihre Abfragen nicht geschrieben wurden, um die vorhandenen Indizes zu nutzen.

Schauen Sie sich nun Ihre Anfrage an:

select data from test where data = 'vwx';

Sie sagten, dass die Tabelle 10 Zeilen hat. Als Faustregel gilt, dass das MySQL Query Optimizer die Verwendung eines Index ablehnt, wenn die Anzahl der zu untersuchenden Zeilen mehr als 5% der Gesamtzahl der Zeilen beträgt.

Lass uns rechnen. 5% von 10 Zeilen sind 0,5 Zeilen. Selbst wenn die Anzahl der Zeilen, in denen Ihre Daten gefunden werden müssen, 1 beträgt, ist dies größer als 0,5. Aufgrund dieser geringeren Anzahl von Zeilen und der gerade erwähnten Indexregel führt MySQL Query Optimizer immer einen Tabellenscan durch.

Da die Spalte dataselbst indiziert ist, wurde mysql anstelle eines Tabellenscans einen Indexscan durchgeführt.

Wenn Sie mit Sicherheit wissen, dass die Testtabelle niemals wachsen wird, können Sie alle Indizes entfernen und Tabellenscans durchführen. Handler-Statusvariablen sollten nicht mehr inkrementiert werden.

RolandoMySQLDBA
quelle
Hallo, danke für die Antwort. Ich hatte versucht, den Index zu entfernen und den Wert durch Ausführen der Abfrage zu überprüfen. Der Wert von Handler_read_rnd_next wird jedoch um 18 erhöht, was mit dem Index um 7 erhöht wurde. Die Tabelle, die ich erwähnt habe, ist nicht festgelegt. In diesem Beispiel habe ich 70 weitere Zeilen in die Tabelle eingefügt, sodass die Gesamtzahl der Zeilen 80 beträgt, und dieselbe Abfrage mit Index für die Spalte 'Daten' ausgeführt, die immer noch nur eine Zeile zurückgibt. Wenn ich jedoch den Wert von 'Handler_read_rnd_next' überprüfe, wird er immer noch um 7 erhöht. Kann ich wissen, warum dieses Flag inkrementiert wird und wie dies eingeschränkt werden kann?
Phanindra
Die genau gleichen Gründe, die ich angegeben habe, gelten immer noch. Ein Index-Scan wurde durchgeführt. Diesmal wurde kein vollständiger Index benötigt. Offensichtlich mussten 7 Blattknoten im BTREE des Index durchlaufen werden, um die eine Zeile zu erhalten. Handler-Statuszähler zeigen die Indexverwendung an. Die einzige Möglichkeit zur Einschränkung besteht darin, den Index wie angegeben vollständig zu entfernen. Ansonsten ist dies immer erwartetes Verhalten. Eine bessere Indizierung komplexerer Tabellenstrukturen und ordnungsgemäß gestalteter Abfragen kann die Anzahl der Handler verringern, sie jedoch niemals vollständig entfernen.
RolandoMySQLDBA
"Als Faustregel wird das MySQL Query Optimizer die Verwendung eines Index ablehnen, wenn die Anzahl der zu untersuchenden Zeilen mehr als 5% der Gesamtzahl der Zeilen beträgt." - das ist sehr sehr hilfreich zu wissen. Gibt es offizielle Unterlagen, die dies unterstützen? Ich danke dir sehr!
Itoctopus
2

Welche Version von MySQL?

Die Gründe, warum dieses Flag erhöht wird, lassen sich am besten hier dokumentieren: http://www.mysqlperformanceblog.com/2010/06/15/what-does-handler_read_rnd-mean/

Kurz gesagt, es ist nur der Zähler der Anzahl der Zeilen, die während eines vollständigen oder teilweisen Tabellenscans in der angegebenen Reihenfolge abgerufen wurden.

Nun, das heißt, ich bekomme ein anderes Ergebnis:

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
quelle
0

Wenn für die Spalte "Daten" ein eindeutiger / primärer Index vorhanden ist, haben Sie diese Abfrage bereits optimiert. Ich kann mir nicht vorstellen, dass dies weiter optimiert werden kann.

Sie können auch überprüfen, ob ein FULL TABLE SCAN durchgeführt wurde oder nicht.

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

Stellen Sie sicher, dass select_scan seinen Wert nicht erhöht hat. Auf diese Weise können Sie überprüfen, ob FULL TABLE SCAN ausgeführt wird oder nicht. Sie sollten versuchen, eine Abfrage zu optimieren, die FULL TABLE SCAN nicht ausführt.

Mahesh Patil
quelle