MySQLの戦闘36 |なぜ一時テーブルは、同じ名前にすることができますか?

前回の記事では、我々は、一時テーブルへのクエリを結合最適化するために時間を使います。その時、私たちはそのように使用されています。

create temporary table temp_t like t1;
alter table temp_t add index(b);
insert into temp_t select * from t2 where b>=1 and b<=2000;
select * from t1 join temp_t on (t1.b=temp_t.b);
复制代码

あなたはなぜそれが一時テーブルを使用し、間違いであってもよいですか?通常のテーブルの直接の使用はまた、そうすることを許可されていませんか?

一時テーブルの特徴は何ですか、なぜそれがこのシナリオに適している:今日はこの質問で始まりますか?

一部の人々は、一時テーブルはメモリテーブルであることを考えるかもしれない:ここでは、私はあなたが質問誤解を明確に支援する必要があります。しかし、二つの概念が、完全に異なります。

  • メモリテーブルは、構築されたテーブルの構文テーブル...エンジン=メモリを作成し、テーブルメモリエンジンの使用を意味します。このデータテーブルは、システムの再起動時にクリアされ、メモリに保存されているが、テーブル構造がまだそこにあるされています。これらの2つの機能に加えて、ビューの点から他の特徴を、より多くの「奇妙」に見える、それは通常のテーブルです。
  • 一時テーブルは、あなたがエンジンのさまざまな種類のを使用することができます。書き込みデータがディスクに書き込まれるときには、InnoDBエンジンや一時テーブルのMyISAMエンジンを使用している場合。もちろん、あなたも一時テーブルメモリのエンジンを使用することができます。

将来的にはメモリと一時テーブルの違いを把握、私たちは一時テーブルを特徴付けるものを見てみましょう。

一時テーブルの特徴

理解を容易にするために、我々は次の一連の操作を見てみましょう。


                                                                            (実施例1つの)図特性一時テーブル

見ることができ、一時的なテーブルには、以下の機能が使用されています:

  1. 内蔵テーブルの構文は、一時テーブルを作成することです....
  2. 一時テーブルは、それが唯一の他のスレッドには見えないセッションにアクセスすることができます作成​​されます。したがって、図テンポラリテーブル作成されたセッションTで、セッションBに閲覧できません。
  3. 同じ名前の一時テーブルは通常のテーブルとすることができます。
  4. タイムテーブルと同じ名前を持つ、通常のセッションで一時テーブルは、ショーが一時テーブルにアクセスするための書類、およびCRUD文を作成し、あります。
  5. ショーテーブルは一時テーブルを表示しませんコマンド。

一時テーブルにのみそれを作成したセッションにアクセスし、そうすることができますので、このセッションが終了したときに、一時テーブルは自動的に削除されます。それは、この機能が原因である私たちは、このシーンを最適化する参加、一時テーブルは、資料の冒頭に特に適していますなぜ?

主な理由は、次の2つの側面が含まれます:

  1. 複数のセッションが同時に存在する場合、一時的なテーブルが最適化結合を実行、同じ名前の別のセッションで、テーブル名を繰り返すことを心配していないテーブルを構築するための課題は失敗しました。原因。
  2. あなたは、データ削除の問題を心配する必要はありません。共通テーブル場合、処理実行クライアントに断線異常が発生した場合、またはデータベースが発生し、異常再起動するだけでなく、具体的には表中に生成された中間データをきれいにします。一時的なテーブルに自動的に回復しますので、この追加の操作は必要ありません。

一時テーブルの応用

スレッド間で同じ名前の衝突は、一時テーブルは、多くの場合、最適化プロセスの複雑なクエリで使用されているので、心配しないでください。これらの中でも、サブライブラリーサブテーブルクロスデータベースクエリシステムは、典型的な使用シナリオです。

通常、サブライブラリーサブテーブルのシーン分散液は、それが異なる論理データベース・インスタンスへの大きなテーブルにあります。たとえば。大きなテーブルHTは、フィールドFに応じて、サブテーブル1024に分割した後、インスタンスデータベース32に分配されます。下図のように:


                                                                             図2の模式的な一部ライブラリサブテーブル

一般に、このサブライブラリシステムは、サブテーブル中間層プロキシを有しています。しかし、データベースに接続するクライアントを直接作成するプログラムの数があり、それには、プロキシこの層、ではありません。

このアーキテクチャでは、パーティション・キーの選択は、「クロス・データベースおよびクロステーブルのクエリを削減」することである基づいています。文のほとんどがFの同等の条件が含まれる場合は、パーティション化キーのFを行うだろう。従って、この層にプロキシが完了した後SQL文を解析し、問い合わせを行うためにこれらのステートメントルーティングテーブル点を決定することができるであろう。

たとえば、次の文:

select v from ht where f=N;
复制代码

この時点で、我々は、スコア(例えば、N%1024)サブテーブルのルールによってシート上にあった必要なデータていることを確認することができます。このステートメントは、ステートメントのサブテーブル、サブライブラリーのサブテーブルのプログラムで最も人気のあるフォームにアクセスする必要があります。

しかし、そこにインデックスk上の別のテーブルがあり、クエリは、このある場合:

select v from ht where k >= M order by t_modified desc limit 100;
复制代码

何の使用クエリパーティションフィールドfが存在しないため、この時点で、唯一のすべての行の条件を満たすためにすべてのパーティションを見つけ、その後、統一行動順を行います。この場合、2つの比較的一般的なアイデアがあります。

最初のアイデアは、であるプロキシレイヤコードの過程で選別実装します。

このアプローチの利点は、記憶メモリの計算に直接関与した後のデータポイントを得るために、速い処理速度です。しかし、この解決策の欠点は、より明白です。

  1. 必要な開発努力は比較的大きいです。当社は、中間層の機能の開発が比較的高く、それは複雑な操作になる場合によって、そのようなグループとして、この文はまだ比較的単純である示し、あるいは、そのような操作に参加します。
  2. プロキシ側の圧力が比較的大きく、特に十分でないメモリとCPUのボトルネックの問題を簡単に表示されます。

もう一つのアイデアは、 MySQLインスタンスに集計表、それぞれのサブライブラリーのデータを取得するには、し、この例で論理演算を行うが要約されています。

上記のようなこの文は、実行の流れはこのようなものになることがあります。

  • 一時表temp_ht上で作成した要約ライブラリは、テーブルには、vは、kは、t_modified 3つのフィールドが含まれています。
  • 様々なサブライブラリーで実行

select v,k,t_modified from ht_x where k >= M order by t_modified desc limit 100;
复制代码

  • サブライブラリーの結果は、表に挿入temp_htを行います。
  • 実行

select v from temp_ht order by t_modified desc limit 100; 
复制代码

結果を取得します。

次のようにこのプロセスは、フローチャートに対応します。


                                                                       図3に概略フロークロスデータベースクエリ

実際に、我々は、多くの場合、各サブライブラリーのための演算量が飽和していない、それは直接、一時テーブル上に置かれることを見つけるのライブラリで32点をtemp_htクエリロジックのこの時点では図3に似ている、あなたは、自分の特定のプロセスを考えることができます。

なぜ、一時テーブルは、同じ名前にすることができますか?

あなたは、これはそれを行う方法で、異なるスレッドが同じ名前を持つ一時テーブルを作成することができ、求めることができますか?

次に、我々はこの問題を見てください。

実施する際には、当社

create temporary table temp_t(id int primary key)engine=innodb;
复制代码

この文は、MySQLのInnoDBテーブルは、テーブルの構造定義ファイルの保存FRMを作成するには、このを与えるだけでなく、テーブルのデータを格納する場所とき。

一時ファイル・ディレクトリにこのFRMファイル、ファイル名の接尾辞が.FRMで、接頭辞は「の#sql {プロセスID} _ {スレッドID} _シリアル番号」ですあなたは、インスタンスの一時ファイルのディレクトリを表示するように選択@@ TMPDIRコマンドを使用することができます。

そして、テーブルにデータを格納するための方法で、我々は、MySQLの異なるバージョンで異なるアプローチを持っています。

  • バージョン5.6以前では、MySQLはデータファイルを格納するために使用されるファイルを、の.ibdために同じ接頭辞、接尾辞を持つディレクトリに一時ファイルを作成します。
  • スタートバージョン5.7からは、MySQLは一時的なデータファイルを格納するために設計された、一時テーブルスペースを導入しました。したがって、我々は、IBDのファイルを作成する必要はありません。

ファイル名の接頭辞ルールから、我々は、実際には、T1のInnoDBと呼ばれる一時テーブルを作成する、ことを見ることができますMySQLのストレージは、我々は通常のテーブルt1でテーブルの名前で作成していると信じて、で異なるので、同じライブラリには、すでに以下の普通のテーブルを持っていますT1の場合は、またはあなたは、一時テーブルt1を再作成することができます。

後で説明を容易にするために、私はあなたの例をあげます。


                                                                                     図4のテーブル一時テーブル

このプロセスは、プロセスIDが1234であり、スレッドIDセッションAが4で、スレッドIDセッションBは5です。だから、一時テーブルのセッションAおよびセッションBが同じ名前ではありません、ディスク上のファイルを作成し、参照してください。

ファイルに加えて、維持するためのMySQLデータテーブルが物理的メモリ内の異なるテーブルを区別するためのメカニズムを持っている必要があり、各テーブルがtable_def_keyに相当します。

  • あなたは同じライブラリ内の同じ名前の共通テーブル2を作成したい場合は、すでに存在しているtable_def_key見つける方法の第二のテーブルを作成するように、通常のテーブルの値table_def_keyは、「ライブラリ名テーブル名+」を得るからですA。
  • 一時テーブルについては、「ライブラリ名+テーブル名」ベースでtable_def_key、だけでなく、「SERVER_ID + thread_idは」に参加。

つまり、AおよびセッションBが作成した2つの一時テーブルt1のセッションでは、それらが異なるtable_def_keyを持って、ディスクのファイル名が異なるので、共存することができます。

各スレッドは一時テーブルの独自のリストを維持して実現しました。リストを横断する前に、もはや普通の運転台がある場合、優先順位リスト上の一時的な操作は、存在しないのであれば、それぞれの時間は、セッション中に手術台は、一時テーブルの名前をチェックし、ときに、セッションの最後に、リンクリストの各一時テーブル、「一時テーブル+テーブル名をドロップ」操作を実行します。

あなたは見つけるでしょう。この時間は、バイナリログはまた、DROP TABLE TEMPORARYにこのコマンドを記録しました。あなたは記述する必要が内側BINLOGするなぜ彼らは、スレッドで一時テーブルをのみアクセスすることができ、不思議に思われる必要がありますか?

それはコピーをスタンバイになるとこれが必要になります。

一時テーブルとプライマリおよび複製

ビンログを書いているので、それは図書館のニーズによってことを意味します。

あなたは想像し、メインライブラリー内の文の次のシーケンスを実行することができます。

create table t_normal(id int primary key, c int)engine=innodb;/*Q1*/
create temporary table temp_t like t_normal;/*Q2*/
insert into temp_t values(1,1);/*Q3*/
insert into t_normal select * from temp_t;/*Q4*/
复制代码

操作が一時テーブルに記録されていない場合は、スタンバイ・データベースは唯一のテーブルt_normalテーブルを作成し、t_normalに挿入し、実行時にライブラリによって調製これらの二つの文のtemp_t binlogのログ、から選択t_normal *に挿入すると、エラーになります「temp_tテーブルは存在しません。」

行は右、うまくフォーマットをBINLOGするように設定されている場合は、言うかもしれませんか?バイナリログ行フォーマットはバイナリログt_normal記録への挿入、つまりこの操作のデータの記録時、理由:write_rowイベントである論理レコードは、「行(1,1)を挿入してください。」

確かにそれはあります。現在binlog_format =行、その後、一時テーブルがステートメントに関連付けられている場合は、バイナリログに記録されることはありません。言い換えれば、唯一binlog_format =なステートメント/混合時に、バイナリログは、一時テーブルのレコードに動作します。

この場合、一時的なテーブル作成ステートメントは、実行するためにスタンバイ・データベースに広がり、そのためのライブラリ装置は、一時テーブルを作成するスレッドを同期します。スレッドが終了したときに、メインライブラリは、それが自動的に一時テーブルを削除しますが、スタンバイ・データベースの同期スレッドが動作して継続されます。だから、今回は実行するために、ライブラリから渡されたメインライブラリにDROP一時テーブルを作成する必要があります。

前に誰かが私に興味深い質問尋ねたスペースはそのまま残っていてもして、それらが記録されているように、テーブルを作成するか、またはALTER TABLEステートメントのいずれかで、記録時にMySQLのバイナリログを:。ドロップテーブルt_normalを実行した場合でも、システムが書かれたバイナリログ記録されます:

DROP TABLE `t_normal` /* generated by server */
复制代码

これは、標準形式に、です。なぜ我々はそれを行う必要がありますか?

drop tableコマンド複数のテーブルを削除することができます。つまり、なぜ今、あなたは知っています。例えば、上記の例では、binlog_format =行設けられ、プライマリ・データベースの「表t_normalドロップ、temp_t」コマンドの実装ならば、それは唯一のバイナリログを記録することができます。

DROP TABLE `t_normal` /* generated by server */
复制代码

スタンバイ・データベースにはテーブルtemp_tがないため、このコマンドは、書き換えた後、実行するためにスタンバイ・データベースに広がり、スレッドライブラリの同期で停止することはありませんでしょう。

そのため、記録時間のbinlog tableコマンドをドロップし、作るために文を書き換える必要があります。「/ *サーバによって生成* /」に書き換えされているこれは、サーバー側のコマンドで示しています。

それは主に来ると複製する場合には、解決すべき別の問題があります:一時テーブルを作成するために、異なるスレッドで同じ名前の主なライブラリは大丈夫ですが、実行はそれに対処する方法を、ライブラリによって渡されますか?

さて、私はあなたの例を与えるだろう、例Sのシーケンス次はM.のライブラリーによって調製されます


一次ライブラリーのT1上の2つのセッションMは、同じ名前を持つ一時テーブルを作成し、二人は、一時テーブルt1を作成する文がライブラリーS.に送信される準備

しかし、スタンバイ・データベースのアプリケーションログのスレッドが共有され、それはこの文の実装を作成するのは、内部のアプリケーションに2件のスレッドがあります。(マルチスレッド複製を開いた場合でも、また、同じライブラリから作業者を実行するように割り当てることができます)。まあ、これは、スレッド同期エラーにつながることはありませんか?

もちろん、そうでない場合は、一時テーブルには、バグではありません。言い換えれば、実施の過程で、ライブラリのスレッドによって調製し、2つの表に対処するには、2つの異なる一時テーブルとしてt1の必要があります。これは、それを達成する方法ですか?

記録時のMySQLのバイナリログは、メインのライブラリは、中のbinlogスレッドIDを書かれたこの文を実行します。このように、アプリケーションスレッドライブラリは、各ステートメントを知っているメインのライブラリスレッドIDの実装を用意し、table_def_key一時テーブルを構築するためにスレッドIDを使用することができます:

  1. T1セッションtable_def_keyライブラリ内の一時テーブルが用意され:ライブラリ名+ T1 +「SERVERIDのMは」+「セッションAのthread_idを」。
  2. table_def_keyライブラリ内の一時テーブルt1セッションBが用意されています。ライブラリ名+ T1 +「SERVERIDのM」+「なthread_idのセッションB。」

異なるtable_def_key、それほど競合ではありません準備アプリケーションスレッドライブラリ内の2つのテーブルのために。

概要

今日、この記事では、私は、一時テーブルの使用状況や特徴を紹介します。

実際には、一般に、より複雑な論理演算を処理するための一時的なテーブル。一時的なテーブルに独自のスレッドごとに表示されていないので、複数のスレッドが同じ処理ロジック、重複した名前の一時テーブルの実行を検討する必要。スレッドが終了すると、一時テーブルは、仕事と例外処理を終了させるための必要性を排除し、自動的に削除することができます。

あなたがbinlog_formatを選択した場合binlog_format一時テーブルがバイナリログに記録するだけでなく、多くの問題を保存されていないオペレーティング=「行」は、これも考慮することがあります。

それは、この一時テーブルの上に私たちに来るとき、ユーザー自身によって作成され、なお、それはまた、ユーザーの一時テーブルと呼ばれることができます。そして、それは対応して、内部の一時テーブル、私はあなたを紹介してきた最初の記事では17です。

最後に、私はバーに思考を残します。

次の文のシーケンスは、一時テーブルを作成することであり、それを名前を変更しました:

                                                        一時テーブルの名前の変更について6つの質問

我々は、一時テーブルのテーブル名を変更するALTER TABLE構文を使用することができ、見ることができますが、名前変更の構文を使用することはできません。あなたはどのような理由を知っていますか?

あなたは、私は次の記事を終了し、あなたがこの問題を議論、コメント欄にあなたの分析を書くことができます。聴いてくれてありがとう、あなたは一緒に読むためにもっとたくさんの友達にこの共有を送るために歓迎されています。

時間の問題について

問題は、以前の期間は、3つのテーブルを次のステートメントに参加するということです、

select * from t1 join t2 on(t1.a=t2.a) join t3 on (t2.b=t3.b) where t1.c>=X and t2.c>=Y and t3.c>=Z;
复制代码

書き換えSTRAIGHT_JOIN場合、どのように、3つのテーブルとどのようにインデックスを作成するために参加指定します。

第一の原則は、BKAアルゴリズムを使用しようとすることです。BKAアルゴリズムを使用した場合、「結果の2つのテーブルを結合する第三のテーブルに話を参加させる」ではないことに注意してください、しかし、直接ネストされたクエリ。

特定の実装は、次のとおりt1.c> = X、t2.c> = Y、> = Z t3.cこれら三つの条件は、最小のデータテーブルを介して濾過した後に選択することを、第一の駆動テーブルとして。この場合には、次の2つの状況が発生する可能性があります。

最初のケースは、テーブルT1が選択された場合、またはT3は、残りの部分は固定されています。

  1. 駆動テーブルがT1である場合には、接続順序はT1-> T2-> T3、インデックスはすなわち、T2​​.Aとt3.bにインデックスを作成され、作成されたテーブルフィールドに駆動されます。
  2. ドライブテーブルはt3がある場合は、接続順序があるT3-> T2-> T1、我々はT2.Bとt1.a.にインデックスを作成する必要があります

同時に、我々はまた、最初のフィールドCドライブのテーブルにインデックスを作成する必要があります。

選出された最初のドライブテーブルは、テーブルT2を、他の2つの条件のフィルタリング効果を評価する必要がある場合に、第2の場合です。

要するに、全体的なアイデアは、私たちは小さなテーブルを駆動するので、小さい良く、データのすべてのセットに参加する時間は、ドライブのテーブルを結合するようにしよう、です。

ます。https://juejin.im/post/5d05ef7fe51d4577407b1d2eで再現

おすすめ

転載: blog.csdn.net/weixin_34301307/article/details/93183426