Heim >Datenbank >MySQL-Tutorial >MYSQL-MySQL-Befehl und Implementierungsmethode HANDLER_MySQL
MySQL hat „seit der Antike“ einen mysteriösen HANDLER-Befehl, und dieser Befehl ist keine Standard-SQL-Syntax, was den Parsing- und Optimierungsaufwand des Optimierers für SQL-Anweisungen reduzieren und dadurch die Abfrageleistung verbessern kann. Einige Freunde sind möglicherweise nicht ruhig, wenn sie dies sehen. Warum wird so etwas Gutes nicht häufig verwendet? Ist das nicht vergleichbar mit dem Handlersocket-Plug-In, das vor einigen Jahren sehr beliebt war?
Also werfen wir zunächst einen Blick auf die Beschreibung der Handler-Syntax:
HANDLER tbl_name OPEN [[AS] alias]
HANDLER tbl_name READ index_name { = |
HANDLER tbl_name READ index_name { FIRST |. NEXT |
HANDLER tbl_name READ { FIRST |. NEXT } [ WHERE where_condition ] [LIMIT … ]
HANDLER tbl_name CLOSE
Aus syntaktischer Sicht kann HANDLER zunächst über den angegebenen Index auf Daten zugreifen. Diese Syntax unterstützt jedoch keine DML-Operationen. Darüber hinaus ist die Leistung des Handler-Befehls aufgrund der Reduzierung der SQL-Analyse wirklich gut. Laut dem einfachen Primärschlüsseltest von Inside ist der Handler-Befehl 40 bis 45 % schneller als SQL. Das Testskript lautet wie folgt:
SET @id=FLOOR(RAND()*1000000); HANDLER sbtest.sbtest1 OPEN AS c; HANDLER C READ `PRIMARY` = (@id); HANDLER C CLOSE;Auf dem 24C-Testserver von Inside lief die 64-Thread-Primärschlüsselabfrage mit fast 37 W QPS, was immer noch sehr beeindruckend ist. Beim Vergleich der SQL-SELECT-Abfrage sind die Gesamttestergebnisse wie folgt:
Die Hauptimplementierung des Befehls HANDLER befindet sich im Quellcode sql_handler.h, sql_handler.cc. Sie können den spezifischen Prozess beobachten, indem Sie einen Haltepunkt festlegen. Die Hauptfunktionseingänge für die obere Schicht von MySQL und die InnoDB-Speicher-Engine-Schicht sind:
Der Code lautet wie folgt:
Sql_cmd_handler_read::execute
Sql_cmd_handler_close::execute
ha_innobase::init_table_handle_for_HANDLER
ha_partition::init_table_handle_for_HANDLER() (Version 7 unterstützt HANDLER-Operationspartitionstabelle)
Inkonsistentes Lesen? ? ?
Gibt alle Spalten im Clustered-Index zurück (auch den Zugriff auf den sekundären Index), anstatt eine bestimmte Spalte zurückzugeben
Der Sekundärindex verwendet nicht das Schlüsselwort LIMIT und kann nur 1 Datensatzzeile
zurückgeben
Schüler, die den Befehl HANDLER kennen, denken möglicherweise, dass es beim HANDLER-Lesen ein Dirty-Read-Problem gibt. Denn in der offiziellen MySQL-Dokumentation heißt es zum HANDLER-Lesen:
Die Handler-Schnittstelle muss kein konsistentes Erscheinungsbild der Daten bereitstellen (z. B. sind Dirty Reads zulässig), sodass die Speicher-Engine Optimierungen verwenden kann, die SELECT normalerweise nicht zulässt.
/* Wir lassen HANDLER die Lesevorgänge immer als konsistente Lesevorgänge durchführen, sogar
angegeben worden wäre
m_prebuilt->select_lock_type = LOCK_NONE;
m_prebuilt->stored_select_lock_type = LOCK_NONE;
Es scheint sinnvoll zu sein, den Befehl HANDLER zum Abfragen des Primärschlüssels zu verwenden. Dies reduziert den Overhead des SQL-Parsers und verbessert die Leistung erheblich. Dafür müssen jedoch große Änderungen an der Anwendung vorgenommen werden, und der größte Vorteil von SQL ist die Standardisierung. Ich glaube, dass dies auch das größte Problem ist, mit dem NoSQL-Datenbanken derzeit konfrontiert sind. Zum Beispiel muss MongoDB, Insider jedes Mal, wenn er eine Abfrage schreibt, die offizielle Befehlsvergleichstabelle öffnen ...