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の詳細な説明

推薦する

包括的なウェブサイト評価ソリューション

<br />「XXXのウェブサイトを見てみませんか?」といった質問をされることもあります...

DockerでSpring Bootアプリケーションを実行する方法

ここ数日、dockerでSpring Bootアプリケーションを実行する方法を勉強してきました。以前...

Vue3を使用してjsで呼び出せるコンポーネントを実装する

目次序文1. 従来のVueコンポーネント1. メインコンポーネントコード: 2. 使用方法3. 成果...

クラウド CentOS で Docker リモート サービス リンクを有効にするための実装手順

ここでは、dockerがインストールされたcentosサーバーを紹介し、リモートリンクサービスを開始...

JS における ES6 継承と ES5 継承の違い

目次継承ES5 プロトタイプ継承ES6 クラス継承両者の違いES5プロトタイプ継承の内部実装ES6 ...

高度な JavaScript フロントエンド開発でよく使用されるいくつかの API の例の詳細な説明

目次ミューテーションオブザーバーAPI特徴インターセクションオブザーバーAPI例えば画像の遅延読み込...

geo モジュールを使用して Nginx でホワイトリストを設定する例

元の構成: http { ...... limit_conn_zone $binary_remote...

Vue ページをリフレッシュするために provide と injection を適用する

目次方法1: 関数を直接呼び出す方法2: provide / inject (静的更新) を使用する...

JavaScriptはシンプルな計算機能を実装します

この記事では、参考までに、簡単な計算機を実装するためのJavaScriptの具体的なコードを紹介しま...

MySQL 更新セットとの違い

目次問題の説明原因分析解決問題の説明最近、奇妙な問い合わせを受けました。更新ステートメントはエラーな...

MySQL データベース インデックスが B+ ツリーの使用を選択するのはなぜですか?

MySQL データベース インデックスが B+ ツリーを使用する理由をさらに分析する前に、データ構...

Linuxでスワップパーティションファイルを作成する方法

スワップの紹介Linux のスワップ (スワップ パーティション) は、Windows の仮想メモリ...

JavaScript で localStorage を使用する方法

.NET の世界に参入したい開発者であれば、何が可能なのかを知る必要があります。 .NET Fram...

React における ref の一般的な使用法の概要

目次Refsとは何か1. 文字列型参照2. コールバック参照React.createRef() 4....

MySQLクエリ条件の一般的な使用法の詳細な説明

この記事では、例を使用して、MySQL クエリ条件の一般的な使用方法を説明します。ご参考までに、詳細...