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

推薦する

CSSは複数の要素をボックスの両端に揃える効果を実現します

要素の両端を揃える配置レイアウトは、実際の開発のいたるところで見られます。これは、フレックスレイアウ...

VMware 仮想化 KVM のインストールと展開のチュートリアルの概要

仮想化1. 環境セントオス7.3 selinuxとファイアウォールを無効にする2. 仮想化環境の構成...

WeChatアプレットが計算機機能を実装

WeChatミニプログラムはますます人気が高まっています。多くの大学生が独学で学んでいるのも見てきま...

HTML でフォーム コントロールを無効にする 2 つの方法: readonly と disabled

Web ページを作成する過程では、フォームがよく使用されます。しかし、フォーム上のコントロールを変更...

航空機戦争ゲームを実装するためのネイティブJS

この記事の例では、参考のために航空機戦争ゲームを実装するためのJSの具体的なコードを共有しています。...

古い Vue プロジェクトに Vite サポートを追加する方法

1. はじめに会社のプロジェクトを引き継いで2年になります。今では毎回プロジェクトを起動するのに1分...

MySQLのパラメータについてお話しましょう

序文:以前の記事では、特定のパラメータの機能についてよく紹介してきました。しかし、MySQL パラメ...

MySQL での外部キーの作成、制約、削除

序文MySQL バージョン 3.23.44 以降では、InnoDB エンジン タイプのテーブルは外部...

CSS を使用して HTML フォーム コントロールを美しくする詳細な例 (フォームの美化)

1. HTML送信ボタンと下部ボタンの基本構文構造1. HTML送信ボタン入力タグで type=&...

新しい要素を作成する3つの方法のまとめ

1つ目: テキスト/HTML経由var txt1="<h1>テキスト。<...

W3C チュートリアル (11): W3C DOM アクティビティ

ドキュメント オブジェクト モデル (DOM) は、プログラムがドキュメントのコンテンツ、構造、およ...

ウェブページのカスタム選択ボックス選択

選択ドロップダウン リスト フォームは誰もがよく知っているかもしれませんが、デフォルトのドロップダウ...

React における setState の同期または非同期の問題の理解

目次1. setState は同期的ですか?非同期ですか? 2. 非同期的に動作する1. React...

Linux CentOS 7.7 システムの VMware インストールに関する詳細なチュートリアル

Linux CentOS 7.7 システムを Vmware にインストールする方法。最小限のインスト...

W3Cチュートリアル(16):その他のW3Cの活動

このセクションでは、その他の重要かつ興味深い W3C アクティビティの概要を説明します。このセクショ...