ホームページ  >  記事  >  データベース  >  MYSQLの謎のHANDLERコマンドと実装方法_MySQL

MYSQLの謎のHANDLERコマンドと実装方法_MySQL

WBOY
WBOYオリジナル
2016-08-20 08:48:091008ブラウズ

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 閉じる

まず、構文の観点から、HANDLER は指定されたインデックスを通じてデータにアクセスできます。ただし、この構文は DML 操作をサポートしません。さらに、SQL 解析の削減により、Handler コマンドのパフォーマンスは非常に優れています。Inside の簡単な主キー テストによると、Handler コマンドは SQL よりも 40% ~ 45% 高速です。テストスクリプトは次のとおりです:


リーリー

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 操作パーティションテーブルをサポートします)

パフォーマンスが良いので、本番環境でもコマンド HANDLER を使用してみてはいかがでしょうか?主な理由は、HANDLER コマンドには次のような重大な問題があるためです:

読み取りに一貫性がありませんか? ? ?

特定の列ではなく、クラスター化インデックス内のすべての列 (セカンダリ インデックス アクセスも含む) を返します
セカンダリ インデックスは LIMIT キーワードを使用せず、レコードの 1 行のみを返すことができます
HANDLER コマンドを知っている学生は、HANDLER の読み取りにダーティ リードの問題があると考えるかもしれません。公式 MySQL ドキュメントには HANDLER の読み取りについて次のように書かれているためです:

ハンドラー インターフェイスはデータの一貫した外観を提供する必要がないため (ダーティ リードが許可されるなど)、ストレージ エンジンは SELECT では通常許可されない最適化を使用できます。 ただし、MySQL のドキュメントには、一貫性のない読み取りが許可されると正確に記載されていることに注意することが重要です。ただし、InnoDB ストレージ エンジンの HANDLER 実装は一貫した読み取りをサポートしています。Insider の個人的なテストによれば、実際にはダーティ読み取りの問題はありません。もちろん、ソース コード自体が READVIEW が関数 init_table_handle_for_HANDLER に割り当てられていることがわかります。また、コメントでもこれを示しています。

/* HANDLER が常に一貫した読み取りとして読み取りを実行できるようにします。
trx 分離レベルが SERIALIZABLE */

として指定されていた場合 m_prebuilt->select_lock_type = LOCK_NONE;

m_prebuilt->stored_select_lock_type = LOCK_NONE;

主キーのクエリには HANDLER コマンドを使用するとよいようです。 SQL パーサーのオーバーヘッドが軽減され、パフォーマンスが大幅に向上します。ただし、そのためにはアプリケーションに大きな変更を加える必要があり、SQL の最大の利点は標準化であることです。これは、NoSQL データベースが現在直面している最大の問題でもあると私は考えています。たとえば、MongoDB では、Insider はクエリを作成するたびに公式のコマンド比較表を開く必要があります...

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。