MySQL には「古くから」謎の HANDLER コマンドがあり、このコマンドには非 SQL 標準構文があり、オプティマイザーの SQL ステートメントの解析と最適化のオーバーヘッドを削減できるため、クエリのパフォーマンスが向上します。これを見て、なぜこんな良いものが普及しないのか、と落ち着かない友人もいるかもしれません。これは、数年前に非常に人気があった handlersocket プラグインに似ていませんか?
それでは、まずハンドラーの構文の説明を見てみましょう:
HANDLER tbl_name OPEN [[AS] エイリアス]
ハンドラー tbl_name READ インデックス名 { = | <= >= < } (value1,value2,…)
ハンドラー tbl_name READ インデックス名 { 最初 | 前へ } [WHERE where_condition] [LIMIT | ]
HANDLER tbl_name READ { FIRST NEXT } [ WHERE where_condition ] [LIMIT … ]
ハンドラー tbl_name 閉じる
Inside の 24C テスト サーバーでは、64 スレッドの主キー クエリがほぼ 37W QPS で実行されましたが、これは依然として非常に印象的です。 SQL SELECT クエリを比較すると、全体的なテスト結果は以下のようになります:
コマンド HANDLER の主な実装は、ソース コード sql_handler.h、sql_handler.cc にあります。ブレークポイントを設定することで、特定のプロセスを観察できます。 MySQL 上位層と InnoDB ストレージ エンジン層の主な関数入口は次のとおりです:
コードは次のとおりです:
Sql_cmd_handler_open::execute
Sql_cmd_handler_read::execute
Sql_cmd_handler_close::execute
ha_innobase::init_table_handle_for_HANDLER
ha_partition::init_table_handle_for_HANDLER() (バージョン 7 は HANDLER 操作パーティションテーブルをサポートします)
読み取りに一貫性がありませんか? ? ?
特定の列ではなく、クラスター化インデックス内のすべての列 (セカンダリ インデックス アクセスも含む) を返します
セカンダリ インデックスは LIMIT キーワードを使用せず、レコードの 1 行のみを返すことができます
HANDLER コマンドを知っている学生は、HANDLER の読み取りにダーティ リードの問題があると考えるかもしれません。公式 MySQL ドキュメントには HANDLER の読み取りについて次のように書かれているためです:
/* HANDLER が常に一貫した読み取りとして読み取りを実行できるようにします。
trx 分離レベルが SERIALIZABLE */
m_prebuilt->stored_select_lock_type = LOCK_NONE;
主キーのクエリには HANDLER コマンドを使用するとよいようです。 SQL パーサーのオーバーヘッドが軽減され、パフォーマンスが大幅に向上します。ただし、そのためにはアプリケーションに大きな変更を加える必要があり、SQL の最大の利点は標準化であることです。これは、NoSQL データベースが現在直面している最大の問題でもあると私は考えています。たとえば、MongoDB では、Insider はクエリを作成するたびに公式のコマンド比較表を開く必要があります...