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

推薦する

MySQL のロックに関する問題

ロックの分類:データ操作の粒度から:テーブルロック:操作時にテーブル全体がロックされます。行ロック:...

Web ページでパラメータ名によって ActiveX コントロールのプロパティに値を割り当てる例

コードをコピーコードは次のとおりです。 <HTML> <ヘッド> <T...

JavaScriptは、ユーザーがチェックボックスをオンにする必要があるプロトコルの例を実装します。

js では、ログインまたは登録を確認する前に、ユーザーが特定の契約書を読むように設定します (使用...

CSS3 アニメーション ボールローリング JS コントロールアニメーション一時停止

CSS3 はアニメーションを作成でき、多くの Web ページのアニメーション画像、Flash アニメ...

面接でよく聞かれる Vue 修飾子 13 個

目次1. 怠惰な2.トリム3.番号4.停止5. キャプチャ6.自分7.一度8.予防する9.ネイティブ...

Vueルーティングはページステータスを復元する操作メソッドを返します

ルートパラメータ、ルートナビゲーションガード: ページが戻ったときに検索結果を保持する需要シナリオ:...

ECMAScript6 におけるマップマッピングの基本概念と一般的な方法

目次マッピングとは何かオブジェクトとマップの違いマップの共通メソッド宣言と初期化割り当てセットキー値...

MySQL の NULL 値に関する体験談と分析チュートリアルシリーズ

目次1. テストデータ2. ヌル値による不便3. スペース、空の値、null をどのように判断すれば...

Vueプロジェクトでのトークン検証ログイン(フロントエンド部分)

この記事の例では、Vueプロジェクトでのトークン検証ログインの具体的なコードを参考までに共有していま...

jsのディープコピーを理解しましょう

目次js ディープコピーデータ保存方法浅いコピー/深いコピーとは何か一般的なディープコピーの実装1....

サラウンドリフレクションロード効果を実現するHTML+CSS

この記事では、主に html + css を使用してサラウンド リフレクション ローディング エフェ...

便利でシンプルなMySQL関数10個

関数0. 現在の時刻を表示するコマンド: select now()。機能: 現在の時刻を表示します。...

CSS3 の新しいレイアウト: flex の詳細な説明

Flexの基本概念フレックス レイアウト (フレックスはフレキシブル ボックスの略)、エラスティック...

CSSはラジオをクリックして2つの画像スタイルを切り替えますが、複数のラジオのうち1つだけをチェックできます。

クリックされたボタンには赤い画像スタイルを実装し、選択されていない他のボタンには灰色の画像スタイルを...

MySQLスローログに関する知識のまとめ

目次1. スローログの紹介2. スローログの練習1. スローログの紹介スロー ログの正式名称はスロー...