最後にSELECT COUNT(*)下は何をしましたか?



テーブルからSELECT COUNT(*)は、別のSQLニーズに共通するものです。

私たちは、一般的に、この文脈では、(一般的なビジネス)ストレージエンジンのテーブルとしてのトランザクションエンジンはInnoDBを使用してMySQLの仕様の使用の行数、NはテーブルであるO(N)の時間計算量COUNT(*)の操作度。

そして、MyISAMテーブルはすぐにテーブルの行にアクセスすることができます。これらの慣行の背景にどの機構であり、あなたが必要とする理由/したい記事が探検するようなものであってもよいです。

ストレージエンジンの2種類で、問題の概要を初めて目、MySQLのCOUNT(*)一部:

ここではこれらの質問では、主に議論することはInnoDBストレージエンジンへ。

A、InnoDBのテーブルのフルCOUNT(*)

主な問題:

1、などの実装プロセス?

2、どのようにカウント数を計算するには?何のカウント結果に影響を与える要因?
3、カウント値が存在?関連するデータ構造は何ですか?
4.なぜInnoDBはテーブルだけを掃引することにより、カウント(*)を達成することができますか?(この記事の最後の問題を参照してください)
5、全体のテーブルのCOUNT(*)操作の場合テーブルスキャンタイプとして、リスクは何ですか?
6、COUNT(*)が関与大きなフィールドを読み取ることが可能な限りオーバーフローページ「*を選択」のような操作が可能かどう?
1、実行するフレーム - サイクル:読み取りカウント+?

1.1基本的な結論は:

  • 全表スキャン、循環の問題。

  • 内部ループ:最初の行を読み込み、その行はカウントに含まかどうかを決定します。

  • 循環はラインカウント処理によってラインが行われます。

1.2 説明:
シンプルSELELCT-SQLの実装フレームワーク、類推INSERT INTO ... SELECTは、同じプロセスです。
以下は、徐々に読んで(カウント++)カウントする方法を精緻化します。

2、実装プロセス?

プロセスの一部を行う、それは、4つの部分に分割されます。

(1)COUNT(*)前処理:SQL SELECT文の前のMySQLサーバ側への実装は、精巧な背中の一部のためのステージを作るために、クライアント側から送信されました。
(2)COUNT(*)プロセス:コード・レベルのプロセス・フレームワークと2つのコア・ステップのコールスタックの一部の簡単なフォーカスを与えます。
(3)行を読み取り:可視性とrow_search_mvcc機能は、それが視認COUNT(*)の結果にどのように影響するかを説明しています。
(4)行数:Evaluate_join_record列が空である、と彼らはカウント処理のCOUNT(*)の結果にどのような影響を与えるかについて説明します。

読者が直接どのようにCOUNT(*)を参照したい場合は、(1)を無視することができ、そして見始めて(2)に直接ジャンプ。

2.1、COUNT(*)前処理メモリ - クライアント端末機能sub_selectからSQLを送信します

呼び出し元のプロセスを参照するためには、予想外ではありません、我々は最初に来て、この関数sub_selectを実行する方法を思い出します。
(1)のMySQLクライアントは、通信プロトコルパケットのMySQLに従って送信SQL文を送信します。
(2)のMySQLサーバーは、プロトコルにより、コマンドタイプ(QUERY)とSQL文(文字列)を解析し、データパケットを受信します。
SQL文パーサ出力から(3)構造化SQL文の発現のために、オブジェクトのクラスに参加します。
PS:ここでは構造だけではなく、純粋に構文構造、意味処理が、テーブルのされている、大まかに言えば、要約リスト(table_list)、条件、サブクエリ構文ターゲット列のリスト(target_list)に参加構造。
テーブル全体のCOUNT(*)-caseにおいて、table_list = [テーブル "T"(別名は "T" である)]、target_list = [ターゲットオブジェクト列( "COUNT(*)" という名前の列)]において、当然のことながら、何WHEREがありません条件、サブクエリや他の構造。
(4)オブジェクトは、2つの重要なメソッドがありJOIN:結合::最適化を()、JOIN ::クエリ最​​適化とクエリ文の実行のために、それぞれのexec()を、。
  • join-は>最適化()、最適化フェーズ((*)の操作後のカウント数でのMyISAMテーブル全体は、ここで少し内容を含むことになります)。

  • join-は> EXEC()、実施段階(フォーカス)、プロセスのInnoDBテーブル数(*)操作の完全な実装を含みます。

(5)join-は>のexec()いくつかのコールの後、sub_select関数の呼び出しは、COUNT(*)を含む単純なSQLを実行します。
sub_selectの(6)END。

2.2、COUNT(*)プロセス(sub_select機能で)

上部およびコードは、関数は、2つのステップ「の実装フレームワーク」の部分をクラス2と対応しているsub_select機能に着目し、比較的簡単なプロセスである - カウント。以下の結論に与えられました:

(1)行読み出し:sub_selectからの相対的なトップレベルのコール、すべてのブランチへの呼び出し最後にrow_search_mvcc機能のいくつかの機能の後に、機能は、メモリに格納された1本のラインを読み出すためInnoDBストレージエンジンからB + -tree構造でありますBUF(UCHAR *)で、以降の処理が使用されます。

ここでは、行ロック、MVCCと可視性の問題の行を取得伴います。もちろん、スナップショットのこのタイプのSELECT COUNT(*)を読み、行ロックを介さず、MVCCの可視性を伴います。詳細にスキップすることができ、「可視性とrow_search_mvcc機能しています。」

(2)ライン数:コード・レベルは、(すなわち、か否かをカウントする++)は、カウントに含まれるべきかどうかを確認するために、読み出し行evaluate_join_record関数で評価されます。

簡潔には、1ライン分のMySQL操作の関数としてCOUNT(引数)自体、括弧内の値であれば引数arg(列全体または行)がNULLでない場合は、カウント++、または行をカウントしません。詳細は、セクション「Evaluate_join_record列が空である」と省略することができます。

これら二つの相のCOUNTの効果(*)の結果は次の通りである:(濾過の二層)

次のように処理SQLレイヤフレームに関連するコードが要約されます。

Q: コードレベル、最初のステップは、(ラインを読んで)二つの枝を持ち、その理由は?
A: インターフェイスレベルからInnoDBは、「最初の行を読んで」とに分け、「次の行を読んで、」2つの異なるプロセスが実行され、(カーソル)の位置を見つけてフォローアップをするために、いくつかの初期作業を行うための最初の行の必要性を読んでこのプロセスは再帰することができます。
私たちは、プログレッシブスキャンテーブル操作にスクリプト/プログラムを使用する場合として、次のSQLが参加する2を達成するために:
次のように特定の本実施形態は、コードに関連し、関係を呼び出す記憶層にSQLエンジン層は、読み出し:(コールスタックを位相基準用)
我々は最終的にrow_search_mvccで同じ機能を実現し、関係なく、読書のどの枝、それを見ることができます。
LOOPは、どのように出力に最終カウント結果を、いくつかの簡単な説明、見てみましょうのrow_search_mvccとevaluate_join_recordを行うには、コードの上にあります。

2.3、およびライン視認性関数row_search_mvcc

ここでは、ラインを見て例のセットといくつかの質問で、視認性のCOUNT(*)に影響を与えます。
Q: 「SELECT COUNT(*)Tからについて 」 または「SELECT MIN(ID)Tから 」 動作、リード線の最初の読出し動作が最小テーブルt(B +ツリー、ページ内の左端のリーフノード)であるの記録?(Ha_index_firstは、なぜまた、最小のキー値を取得するためにrow_search_mvccを呼びます?)
A: 必ずしもそうではありません。視界ラインの問題もあるので、でもMIN(ID)は、必ずしも、IDで最小のラインを読んでいない、実際には現在のトランザクション内のステートメントを取るためにindex_readは、最小のインデックスレコードに表示されます。また、それがあるべきようrow_search_mvccに前述join_read_firstとjoin_read_next「同じもの」が反映されます。
Q: 図は、最後に尋ねたため、トランザクションXは、5または10にのみスキャン実行中X-COUNT(*)(RU(読み取りコミット)分離レベル、および完全なC-挿入(100)されている場合にはそのレコードは)トランザクションC-インサート(100)の後に、その後、X-COUNT(*)を終了した読み取り処理は100で見ることができた後に、このレコードはそれは、完成されましたか?
採用MYSQL戦略は、X-countが(*)バックに100本の記録を読むことができる「何ものを読むことです」。

2.4、evaluate_join_record列は空です

Q: どのようにカウントに含まライン?
A: どちらの場合も、我々は数に含ま行を読み込みます。
(1)COUNTパラメータはカラムの関数である場合、読み出し行によって決定され、カラムは、カラムNULL可能NULLかどうかの値かどうかを定義する;両方がYES、COUNTがカウントされていないいる場合、カウント又は数に。
  • 例えばSELECTのCOUNT(COL_NAME)Tから

  • COL_NAMEは、主キー、ユニークキー、非一意キー、非インデックスフィールドかもしれ

それが決定されたパラメータである場合(2)COUNTの*付きであれば、そうでない場合は、カウント++、それは無視され、NULLである、行全体のこの部分がNULLであるかどうかを判断します。
  • 例えば-1。TからSELECT COUNT(*)

  • 例えば-2。SELECT COUNT(B. *)A左からB ON A.id = B.idをJOIN

Q: 具体的には、tはテーブルIDフィールドであるTからのSELECT COUNT(ID)の主キーは、次にどのように、ですか?
A: 実際にはCOUNT(*)に相当。COUNT(*)、または完全にデータ要求を決定するために、主キーがあるため、COUNT(pk_col)の両方がNULLではないので、現在表示テーブルの行の数を得るために使用することができるような表現をCOUNT。
Q: のInnoDB COUNT(*)操作上の問題のためのユーザレベルを最適化
A: この問題は、テーブルの行数を取得するnull以外のユニークなキーをスキャンし、業界おなじみの問題ですが、バイト関与の数がはるかに少ない(社長とテーブルの主キー、より多くの時間との間のユニークなキーの長さの差)であってもよいです、IOの多くの比較的小さな出費。
関連には、次のコールスタックを参照してください。
第二に、データ構造
Q: メモリ変数に格納されたCOUNT値はありますか?
この1中の発現COUNT(*)に保存され、SQLを解析した後、((Item_sum_count *)item_sum) - >数
上記の我々の以前の「COUNT(*)前処理」セクション次のJOIN図1に示す構造をリコール。
ターゲットがJOINた構造への各SQLステートメント、(結合)のために、すなわちSQLパーサが発現されます。結果のためのリストresult_field_list列を作成し、移入、リストの各要素は、対象の列(Item_result_field *)オブジェクト(ポインタ)の結果です。
COUNT(*)は-caseにおいて、結果リストは、1列のみの要素が含まれ、(Item_sum_count:パブリックItem_result_field)オブジェクトのタイプ(名前=「COUNT(*)」)、特定のクラスメンバ変数の数も望まれます。

三、MyISAMテーブルのフルCOUNT(*)

MyISAMのエンジンは、一般的に、実際の業務で使用されていないので、次のように、だけで簡単に説明:
1、MyISAMテーブル-COUNT(*)操作は、操作の複雑さをO(1)時間です。
図2に示すように、メモリ・カウント変数はファイルのカウント値の値で初期化され、各ファイルの各コピーと共にメモリ内のテーブルにはメタ情報のMyISAM -count値は、読み取られます。
3、T tからSELECT COUNT(*)は、メモリに対応する変数値テーブルをカウントする直接読み取ります。
4、カウント値とファイルメモリのカウント値が書き込み操作によって更新されるように、テーブルレベルのロックの一貫性が保証されます。
図5に示すように、テーブルロック書き込みがシリアル化することを確実にするために、スレッドのすべてのユーザに対して同じタイミングをロックまたは読み取り、またはデータのみの状態に参照されます。
第四に、いくつかの問題
Q: 分割操作の開始実行COUNT(*)の間のMyISAMとInnoDBの?
  • 共通:SQL層は、データ構造は同じSQL構文解析した後、カウント変数が結果Item_sum_count型の列としてオブジェクトに存在している、すなわち、一般的に存在する、プロセスは、クライアントに返される同様である - カウント変数割当を介しクライアントへのMySQLの通信プロトコルバック。

  • 差分:カウント値計算のInnoDBは、SQLの実行フェーズで行われ、それ自体が持つMyISAMテーブルがあることを示す、メモリ内のメタ情報テーブルROW_COUNT値、SQLにヒントオプティマイザにタグストレージエンジンによって最適化相を含みます行の正確な数を保存するために使用されるテーブルのストレージエンジンは、あなたは、アクチュエータを再入力することなく、直接得ることができます。

BLOG住所www.liangsonghua.com

マイクロチャンネル公衆数に焦点:保存卵の黒板には、よりエキサイティングな取得します!

公開番号説明:Jingdongの中での作業に技術の洞察を共有し、同様JAVA技術と業界のベストプラクティスとして、それらのほとんどは、再現性、実用的です理解することができます


おすすめ

転載: juejin.im/post/5e4f35ed6fb9a07c8e6a2c61