MySQL 8.0 の非表示インデックスの詳細な説明

MySQL 8.0 の非表示インデックスの詳細な説明

言葉

MySQL 8.0 は最初のバージョンから 4 年を経てリリースされました。バージョン 8.0 では、機能とコードの面で大幅な改善と再構築が行われました。 DBA サークルの友人とコミュニケーションをとったところ、ほとんどの人がまだバージョン 5.6 と 5.7 を使用しており、少数の人が MySQL 8.0 を採用していることがわかりました。データベース開発のペースに遅れずについていき、テクノロジーのメリットをできるだけ早く享受するために、Youzan のデータベース システムに MySQL 8.0 を導入する予定です。

実装前に、MySQL 8.0 の新機能、構成パラメータ、アップグレード方法、互換性などについて一連の調査とテストを実施します。今後さらに多くの記事が公開される予定です。この記事は、MySQL 8.0 の新機能について初めて知るためのものです。非表示のインデックスについてお話ししましょう。

目に見えないインデックス

非表示のインデックスはオプティマイザを参照します。実行プランを分析する際 (デフォルト)、オプティマイザは非表示属性が設定されたインデックスを無視します。

なぜデフォルトになっているのでしょうか? optimizer_switch で use_invisible_indexes=ON を設定すると、非表示のインデックスを引き続き使用できます。

では、早速いくつかの例をテストしてみましょう。

非表示のインデックスを設定する方法

キーワード VISIBLE|INVISIBLE を指定して create table、create index、alter table を使用することで、インデックスの可視性を設定できます。

mysql> テーブル t1 (i int, を作成
   > j int,
   > k 整数、
   > インデックス i_idx (i) 非表示) engine=innodb;
クエリは正常、影響を受けた行は 0 行 (0.41 秒)

mysql> t1 (j) に非表示のインデックス j_idx を作成します。
クエリは正常、影響を受けた行は 0 行 (0.19 秒)
レコード: 0 重複: 0 警告: 0

mysql> テーブル t1 を変更し、インデックス k_idx (k) を非表示に追加します。
クエリは正常、影響を受けた行は 0 行 (0.10 秒)
レコード: 0 重複: 0 警告: 0

mysql> information_schema.statistics から index_name,is_visible を選択します。ここで、table_schema='test' かつ table_name='t1' です。
+------------+-------------+
| インデックス名 | IS_VISIBLE |
+------------+-------------+
| i_idx | いいえ |
| j_idx | いいえ |
| k_idx | いいえ |
+------------+-------------+
セット内の 3 行 (0.01 秒)

mysql> テーブル t1 を変更してインデックス i_idx を表示します。
クエリは正常、影響を受けた行は 0 行 (0.06 秒)
レコード: 0 重複: 0 警告: 0

mysql> information_schema.statistics から index_name,is_visible を選択します。ここで、table_schema='test' かつ table_name='t1' です。
+------------+-------------+
| インデックス名 | IS_VISIBLE |
+------------+-------------+
| はい |
| j_idx | いいえ |
| k_idx | いいえ |
+------------+-------------+
セット内の 3 行 (0.00 秒)

目に見えないインデックスの役割

多数の履歴インデックスに直面し、数回の開発と新旧開発者の交代を経て、特に 100G を超える大きなテーブルに遭遇した場合、DBA はおそらくインデックスを直接削除することを敢えてしません。インデックスを直接削除すると、データベースの安定性のリスクが高まります。

非表示インデックス機能を使用すると、DBA は、データベースの低速クエリ レコードとスレッドの実行状態を監視しながら、インデックスを非表示に設定できます。データベースに関連する低速クエリが長期間存在せず、thread_running が比較的安定している場合は、インデックスをオフラインにすることができます。それ以外の場合は、インデックスをすぐに表示できるように設定し、ビジネス アクセスを復元できます。

Invisible Indexes はサーバー レベルの機能であり、エンジンとは関係がないため、すべてのエンジン (InnoDB、TokuDB、MyISAM など) で使用できます。

非表示のインデックスを設定した後、実行プランはインデックスを使用できません

mysql> show テーブル t2 \G を作成します
************************** 1. 行 ****************************
    表: t2
テーブルの作成: CREATE TABLE `t2` (
 `i` int NOT NULL AUTO_INCREMENT、
 `j` int NOT NULL、
 主キー (`i`)、
 ユニークキー `j_idx` (`j`) /*!80000 非表示 */
) エンジン=InnoDB デフォルト文字セット=utf8mb4 照合=utf8mb4_0900_ai_ci
セット内の1行(0.01秒)
mysql> t2(j) に値(1),(2),(3),(4),(5),(6),(7) を挿入します。
クエリは正常、7 行が影響を受けました (0.04 秒)
記録: 7 重複: 0 警告: 0


mysql> t2 から j=3\G を選択する場合の説明
************************** 1. 行 ****************************
      id: 1
 選択タイプ: シンプル
    テーブル: t2
  パーティション: NULL
     タイプ: すべて
可能なキー: NULL
     キー: NULL
   キー長さ: NULL
     参照: NULL
     行数: 7
   フィルター: 14.29
    追加: where の使用
セットに 1 行、警告 1 回 (0.01 秒)

mysql> テーブル t2 を変更してインデックス j_idx を表示します。
クエリは正常、影響を受けた行は 0 行 (0.08 秒)
レコード: 0 重複: 0 警告: 0

mysql> t2 から j=3\G を選択する場合の説明
************************** 1. 行 ****************************
      id: 1
 選択タイプ: シンプル
    テーブル: t2
  パーティション: NULL
     型: 定数
可能なキー: j_idx
     キー: j_idx
   キーの長さ: 4
     参照: 定数
     行数: 1
   フィルター: 100.00
    追加: インデックスの使用
セットに 1 行、警告 1 回 (0.01 秒)

非表示インデックスの使用に関する注意事項

この機能は、主キー以外のインデックス (明示的または暗黙的) に適用されます。

非表示のインデックスは、主キー以外のインデックス用です。主キーを非表示に設定することはできません。ここでの主キーには、明示的な主キーまたは暗黙的な主キーが含まれます (主キーがない場合は、主キーの一意のインデックスに昇格されます)。次の例を使用して、このルールを説明します。

mysql> テーブル t2 を作成します (
   >i int は null ではない、
   >j int は null ではありません、
   >ユニークな j_idx (j)
   >) エンジン = InnoDB;
クエリは正常、影響を受けた行は 0 行 (0.16 秒)

mysql> information_schema.statistics から index_name,is_visible を選択します。ここで、table_schema='test' かつ table_name='t2' です。
+------------+-------------+
| インデックス名 | IS_VISIBLE |
+------------+-------------+
| j_idx | はい |
+------------+-------------+
セット内の 1 行 (0.00 秒)

### 主キーが存在しない場合は、一意キーは暗黙的な主キーとして扱われ、非表示に設定することはできません。
mysql> テーブル t2 を変更し、インデックス j_idx を非表示にします。
エラー 3522 (HY000): 主キー インデックスを非表示にすることはできません
マイSQL>
mysql> テーブル t2 を変更して主キーを追加します (i);
クエリは正常、影響を受けた行は 0 行 (0.44 秒)
レコード: 0 重複: 0 警告: 0

mysql> information_schema.statistics から index_name,is_visible を選択します。ここで、table_schema='test' かつ table_name='t2' です。
+------------+-------------+
| インデックス名 | IS_VISIBLE |
+------------+-------------+
| j_idx | はい |
| プライマリ | はい |
+------------+-------------+
セットに2行(0.01秒)

mysql> テーブル t2 を変更し、インデックス j_idx を非表示にします。
クエリは正常、影響を受けた行は 0 行 (0.04 秒)
レコード: 0 重複: 0 警告: 0

mysql> information_schema.statistics から index_name,is_visible を選択します。ここで、table_schema='test' かつ table_name='t2' です。
+------------+-------------+
| インデックス名 | IS_VISIBLE |
+------------+-------------+
| j_idx | いいえ |
| プライマリ | はい |
+------------+-------------+
セットに2行(0.01秒)

force /ignore index(index_name) 非表示のインデックスにはアクセスできません。アクセスするとエラーが報告されます。

mysql> select * from t2 force index(j_idx) where j=3;
エラー 1176 (42000): キー 'j_idx' がテーブル 't2' に存在しません

インデックスを非表示に設定するにはMDLロックを取得する必要があり、長いトランザクションが発生するとデータベースのジッタが発生する可能性があります。

一意のインデックスは非表示に設定されていますが、これはインデックス自体の一意性制約が無効であることを意味するものではありません。

mysql> t2 から * を選択します。
+---+----+
| 私 | j |
+---+----+
| 1 | 1 |
| 2 | 2 |
| 3 | 3 |
| 4 | 4 |
| 5 | 5 |
| 6 | 6 |
| 7 | 7 |
| 8 | 11 |
+---+----+
セット内の行数は 8 です (0.00 秒)
mysql> t2(j) に値(11) を挿入します。
エラー 1062 (23000): キー 't2.j_idx' のエントリ '11' が重複しています

まとめ

実のところ、特に言うことはありませんが、皆様の楽しいご利用を祈っています。

-終わり-

以上がMySQL 8.0の不可視インデックスの詳しい説明です。MySQL 8.0の不可視インデックスの詳細については、123WORDPRESS.COMの他の関連記事にも注目してください!

以下もご興味があるかもしれません:
  • MySQL フルテキスト インデックス、ジョイント インデックス、Like クエリ、JSON クエリのうち、どれが高速ですか?
  • MySQL全文インデックスを使用して検索エンジンのサンプルコードの簡易版を実現する
  • MySQLが全文インデックス共有を実現
  • MySQL フルテキストインデックスアプリケーションに関する簡単なチュートリアル
  • MySQL全文インデックスに基づく詳細な理解
  • MySQLインデックスが失敗するいくつかの状況の詳細な分析
  • MySQL共通インデックスとユニークインデックスの選択に関する詳細な分析
  • MySQL B-Tree インデックスの簡単な分析
  • MySQL 8.0 の降順インデックス
  • MySQL 8.0 のインデックス スキップ スキャン
  • MySQL インデックスの一般的な問題の概要
  • MySql インデックスはクエリ速度を向上させる一般的な方法のコード例
  • MySQL全文インデックスの原理と欠点

<<:  Docker イメージ + nginx を使用して Vue プロジェクトをデプロイする方法

>>:  React Hooksの詳細な説明

推薦する

Dockerのyumソースの設定とCentOS7へのインストールの詳細な説明

ここではCentOS7が使用されており、カーネルバージョンは [root@localhost ~]#...

HTML で中国語を UTF-8 に変換する方法

HTMLでは、中国語のフレーズ「學好好學」は「學好好學」と表現できます。プロジェクトでは、SMSアラ...

Vue でのルータービューコンポーネントの使用に関する詳細な説明

Vue プロジェクトを開発する場合、さまざまなコンポーネント ページを表示するために切り替えることが...

tdが空の場合に境界線を表示する方法

以前、CSS を使用してテーブルの border + bordercolordark + borde...

React Nativeがシミュレータにリンクできない件について

React Native は、現在人気のオープンソース JavaScript ライブラリ React...

プライベートDockerリポジトリであるHarborをインストールするための詳細な手順

Harborのインストールは非常に簡単ですが、Dockerログインで行き詰まってしまいました。このブ...

display または visibility を通じて HTML 要素を表示または非表示にする

場合によっては、特定の条件に基づいて Web ページ内の HTML 要素を表示するか非表示にするかを...

vue+element で動的スキニングを実装するためのサンプルコード

プロジェクトのテーマがすべての人の美的感覚を満足できないこともあります。このとき、スキン変更機能は非...

CocosCreatorでクールなレーダーチャートを描く方法

目次序文プレビュー文章グラフィックコンポーネントプロパティ機能グリッドを描く軸角度を計算するスケール...

DockerでLNMPアーキテクチャを展開する方法

環境要件: IPホスト名192.168.1.1ノード1プロジェクト計画:コンテナネットワークセグメン...

JavaScript ベースのシンプルなカルーセルの実装

この記事では、シンプルなカルーセルを実装するためのJavaScriptの具体的なコードを参考までに紹...

AngularとIonicのライフサイクルとフック関数を素早く理解するための記事

目次角度成し遂げる呼び出し順序知らせイオニックionic はページのライフサイクルをどのように処理し...

.htaccess を使用して特定の IP からの Web サイトへのアクセスを禁止する方法

序文コストを考慮して、ほとんどのウェブマスターは、多数の小規模なウェブサイト用にサーバーを個別に購入...

Vueは画像のドラッグアンドドロップ機能を実装します

この記事の例では、画像のドラッグアンドドロップ機能を実現するためのVueの具体的なコードを参考までに...

HTMLでのラジオ値の取得、割り当て、登録の詳細な説明

1. ラジオのグループ化名前が同じであれば、それらはグループであり、つまり、次のようにグループ内で選...