[MySQL](13)MySQLインデックス最適化分析について話す

前書き:テクノロジーが大好きで詩が書けるビッグデータ開発者「ユンチー」です。ニックネームは、[ 云之祁祁,或雨于渊 ]私が本当に好きな王安師の詩の行に由来しています。


ブログは、あなたが学んだことを少し要約して記録することである一方で、ビッグデータに興味を持っているより多くの友人を助けることです。あなたも数据中台、数据建模、数据分析以及Flink/Spark/Hadoop/数仓开发興味があるなら、あなたは私のダイナミックなhttps://blog.csdn.net/BeiisBeiに集中することができます、私たちはデータの価値をタップしましょう-


每天都要进步一点点,生命不是要超越别人,而是要超越自己! (ง •_•)ง

1つは、インデックスの概念です。

1.1とは

MySQLのインデックスの公式定義は次のとおりです。インデックスは、MySQLがデータを効率的に取得するのに役立つデータ構造です。インデックスの本質を知ることができます。インデックスはデータ構造です。行がデータ構造の適切な順序をすばやく見つけるので、簡単に理解できます

データベースシステムは、データに加えて、特定の検索アルゴリズムを満たすデータ構造も維持します。これらのデータ構造は、特定の方法でデータを参照(ポイント)するため、高度な検索アルゴリズムをこれらのデータ構造に実装できます。このデータ構造がインデックスです。次の図は、可能なインデックス作成方法の例です。

ここに写真の説明を挿入
左側はデータテーブルで、7つのレコードの2つの列があり、左端はデータレコードの物理アドレスです。Col2の検索を高速化するために、右に示すようなバイナリ検索ツリーを維持できます。各ノードには、インデックスキー値と、対応するデータレコードの物理アドレスへのポインタが含まれているため、特定の複雑さの範囲内でバイナリ検索を使用できます。対応するデータを取得して、条件を満たすレコードをすばやく取得します。

一般的に、インデックス自体も非常に大きく、すべてをメモリに格納することは不可能であるため、インデックスはインデックスファイルの形でディスクに格納されることがよくあります。

1.2長所と短所

利点:

  • データ取得の効率を改善し、データベースのIOコストを削減します。
  • インデックス列でデータを並べ替えると、データの並べ替えのコストが削減され、CPU消費が削減されます。

短所:

  • インデックスはクエリ速度を大幅に向上させますが、テーブルのINSERT、UPDATE、DELETEなどのテーブルの更新速度を低下させます。テーブルを更新する場合、MySQLはデータを保存するだけでなく、インデックスファイルが更新されるたびにインデックスファイルを保存してインデックス列フィールドを追加する必要があるため、更新によってキー値が変更された後、インデックス情報を調整します。
  • 実際、インデックスは、プライマリキーフィールドとインデックスフィールドを格納し、エンティティテーブルのレコードを指すテーブルでもあるため、インデックス列もスペースを占有します。

2、MySQLインデックス

2.1Btreeインデックス

MySQLはBtreeインデックスを使用します。

ここに写真の説明を挿入

【初期化入門】

Bツリーの場合、水色のブロックはディスクブロックと呼ばれます。各ディスクブロックには、いくつかのデータ項目(濃い青色で表示)とポインター(黄色で表示)が含まれていることがわかります。

たとえば、ディスクブロック1にはデータ項目17と35が含まれ、ポインタP1、P2、P3、

P1は17より小さいディスクブロックを示し、P2は17〜35のディスクブロックを示し、P3は35より大きいディスクブロックを示します。

実際のデータはリーフノード、つまり3、5、9、10、13、15、28、29、36、60、75、79、90、99に存在します。

非リーフノードは実際のデータのみを格納し、検索方向をガイドするデータ項目のみを格納します。たとえば、17と35は実際にはデータテーブルに存在しません。

【検索プロセス】

データ項目29を検索する場合は、最初にディスクブロック1をディスクからメモリにロードします。この時点でIOが発生します。バイナリ検索を使用して、メモリ内の29が17〜35であることを確認します。ディスクブロック1のP2ポインタをロックします。時間は(ディスクIOと比較して)非常に短く、無視できます。ディスクブロック3は、ディスクブロック1のP2ポインターのディスクアドレスを介してディスクからメモリにロードされ、2番目のIOが発生します。29は26〜30で、ロックされています。ディスクブロック3のP2ポインタは、ポインタを介してディスクブロック8をメモリにロードし、3番目のIOが発生します。同時に、メモリ内でバイナリ検索を実行して29を検索し、クエリを終了して、合計3つのIOを検出します。

実際の状況では、3レベルのB +ツリーは数百万のデータを表すことができます。数百万のデータ検索に必要なIOが3つだけの場合、パフォーマンスは大幅に向上します。インデックスがない場合、各データ項目には1つのIOがあります。 、次に、合計数百万のIOが必要になりますが、これは明らかに非常に高価です。

2.2 B +ツリーインデックス

ここに写真の説明を挿入

B + TreeとB-Treeの違い

1)Bツリーのキーワードとレコードをまとめます。リーフノードは外部ノードと見なすことができ、情報は含まれません。B+ツリーの非リーフノードには、キーワードと次のノードへのインデックスのみがあり、レコードのみが配置されます。リーフノード。

2)Bツリーでは、レコードがルートノードに近いほど、検索時間が速くなります。キーワードが見つかっている限り、レコードの存在を判別できます。B+ツリーの各レコードの検索時間は基本的に同じであり、ルートノードから開始する必要があります。リーフノードに移動し、リーフノードのキーワードを比較します。

この観点から、BツリーのパフォーマンスはB +ツリーよりも優れているように見えますが、実際のアプリケーションでは、B +ツリーのパフォーマンスは優れています。B +ツリーの非リーフノードは実際のデータを格納しないため、各ノードが保持できる要素の数はBツリーの数より多く、ツリーの高さはBツリーのそれよりも低くなります。これにはディスクアクセスの数を減らすという利点があります。

B +ツリーは、Bツリーよりもレコードを見つけるためにより多くの比較を必要としますが、1回のディスクアクセスの時間は、数百または数千のメモリ比較の時間と同等です。したがって、実際のB +ツリーのパフォーマンスは向上する可能性があり、B +はツリーのリーフノードは、シーケンシャルトラバーサルを容易にするためにポインタを使用して相互に接続されます(たとえば、ディレクトリ内のすべてのファイル、テーブル内のすべてのレコードの表示など)。これが、多くのデータベースとファイルシステムがB +ツリーを使用する理由です。

思考:B +ツリーがBツリーよりも実際のアプリケーションのオペレーティングシステムのファイルインデックスとデータベースインデックスに適しているのはなぜですか?

1)B +ツリーのディスク読み取りおよび書き込みコストが低い

B +ツリーの内部ノードには、キーワードの特定の情報へのポインターがありません。したがって、その内部ノードはBツリーよりも小さくなります。同じ内部ノードのすべてのキーワードが同じディスクブロックに格納されている場合、ディスクブロックが保持できるキーワードは多くなります。検索する必要のあるキーワードは、一度にメモリに読み込まれます。相対的に言えば、IOの読み取りと書き込みの数は減少します。

2)B +ツリーのクエリ効率はより安定しています

非終端点は、最終的にファイルのコンテンツを指すノードではなく、リーフノード内のキーワードのインデックスのみであるためです。したがって、キーワード検索では、ルートノードからリーフノードへのパスを使用する必要があります。すべてのキーワードクエリのパス長は同じであるため、各データのクエリ効率は同じになります。

2.3クラスター化インデックスと非クラスター化インデックス

クラスター化されたインデックスは、個別のインデックスタイプではなく、データの保存方法です。「クラスタリング」という用語は、データ行と隣接するキー値クラスターが一緒に格納されることを意味します。次の図に示すように、左側のインデックスはクラスター化されたインデックスです。これは、ディスク上のデータ行の配置がインデックスの順序と一致しているためです。

ここに写真の説明を挿入

クラスター化インデックスの利点:クラスター化インデックスの順序に従って、クエリが特定の範囲のデータを表示する場合、データは密接に接続されているため、データベースは複数のデータブロックからデータを抽出する必要がないため、多くのio操作を節約できます。

クラスター化インデックスの制限:mysqlデータベースの場合、現在、innodbデータエンジンのみがクラスター化インデックスをサポートしていますが、Myisamはクラスター化インデックスをサポートしていません。データの物理ストレージは1種類のみであるため、各Mysqlテーブルは1つのクラスター化インデックスのみを持つことができます。通常の状況では、これはテーブルのプライマリキーです。

クラスター化されたインデックスのクラスター化特性を最大限に活用するには、innodbテーブルのプライマリキー列で可能な限り順序付きシーケンシャルIDを使用する必要があり、uuidなどの順序なしIDを使用することはお勧めしません。

2.4時間の複雑さ(拡張)

同じ問題は異なるアルゴリズムで解決でき、アルゴリズムの品質はアルゴリズムの効率、さらにはプログラムにも影響します。アルゴリズム分析の目的は、適切なアルゴリズムを選択し、アルゴリズムを改善することです。
時間の複雑さは、アルゴリズムを実行するために必要な計算作業の量を指し、大きなOで次のように表されます。O(...)
ここに写真の説明を挿入

3、MySQLインデックス分類

3.1単一値インデックス

概念:インデックスには単一の列のみが含まれ、テーブルには複数の単一列のインデックスを含めることができます。
構文:

//所表一起创建:

CREATE TABLE customer (
	id INT(10) UNSIGNED AUTO_INCREMENT ,
	customer_no VARCHAR(200),
	customer_name VARCHAR(200), 
	PRIMARY KEY(id), 
	KEY (customer_name)  // Σ(っ °Д °;)っ
);

//单独建单值索引:
CREATE INDEX idx_customer_name ON

3.2一意のインデックス

概念:インデックス列の値は一意である必要がありますが、null値は許可されます

//随表一起创建: 
CREATE TABLE customer (
	id INT(10) UNSIGNED AUTO_INCREMENT ,
	customer_no VARCHAR(200),
	customer_name VARCHAR(200), 
	PRIMARY KEY(id), 
	KEY (customer_name), 
	UNIQUE (customer_no)   // Σ(っ °Д °;)っ
);

//单独建唯一索引: 
CREATE UNIQUE INDEX idx_customer_no ON customer(customer_no);

3.3プライマリキーインデックス

概念:主キーを設定した後、データベースは自動的にインデックスを作成し、innodbはクラスター化されたインデックスです

//随表一起建索引
CREATE TABLE customer (
	id INT(10) UNSIGNED AUTO_INCREMENT ,
	customer_no VARCHAR(200),
	customer_name VARCHAR(200), 
	PRIMARY KEY(id)   // Σ(っ °Д °;)っ
);

//单独建主键索引:
ALTER TABLE customer add PRIMARY KEY customer(customer_no);

//删除建主键索引:
ALTER TABLE customer drop PRIMARY KEY ;

//修改建主键索引:
必须先删除掉(drop)原索引,再新建(add)索引

3.4複合インデックス

概念:つまり、インデックスには複数の列が含まれます

随表一起建索引: 
CREATE TABLE customer (
	id INT(10) UNSIGNED AUTO_INCREMENT ,
	customer_no VARCHAR(200),
	customer_name VARCHAR(200), 
	PRIMARY KEY(id), 
	KEY (customer_name), 
	UNIQUE (customer_name), 
	KEY (customer_no,customer_name)  // Σ(っ °Д °;)っ
);

单独建索引: 
CREATE INDEX idx_no_name ON customer(customer_no,customer_name);

3.5基本構文

オペレーティング コマンド
作成する CREATE [UNIQUE] INDEX [indexName] ON table_name(column))
削除 DROP INDEX [indexName] ON mytable;
見る table_name \ Gからインデックスを表示
Alterコマンドを使用する ALTER TABLE tbl_name ADD PRIMARY KEY(column_list):このステートメントは、プライマリキーを追加します。これは、インデックス値が一意である必要があり、NULLであってはならないことを意味します。
ALTER TABLE tbl_name ADD PRIMARY KEY(column_list)
ALTER TABLE tbl_name ADD INDEX index_name(column_list):共通のインデックスを追加します。インデックス値は複数回表示される可能性があります。
ALTER TABLE tbl_name ADD FULLTEXT index_name(column_list):このステートメントは、フルテキストインデックス付けのインデックスをFULLTEXTとして指定します。

第四に、インデックス作成のタイミング

4.1インデックス作成に適した状況

  • 主キーは自動的に一意のインデックスを作成します
  • クエリ条件として頻繁に使用されるフィールドにはインデックスを付ける必要があります
  • クエリ内の他のテーブルに関連付けられているフィールドをクエリし、外部キーの関係のインデックスを作成します
  • 単一キー/複合インデックス選択の問題、複合インデックスはより費用効果が高い
  • クエリ内のソート済みフィールド。ソート済みフィールドにインデックスを介してアクセスすると、ソート速度が大幅に向上します。
  • クエリの統計またはグループ化フィールド

4.2インデックスの作成には適していません

  • テーブルレコードが少なすぎます
  • テーブルまたはフィールドを頻繁に追加、削除、および変更する
  • Where条件で使用されていないフィールドはインデックス付けされていません
  • 不十分なフィルタリングはインデックス作成には適していません

おすすめ

転載: blog.csdn.net/BeiisBei/article/details/108524474