MySQLの整数および文字列インデックスの無効化または暗黙的な変換に関する簡単な説明

MySQLの整数および文字列インデックスの無効化または暗黙的な変換に関する簡単な説明

問題の概要

今日、仕事中に、DBA が突然、SQL に暗黙的な変換があり、インデックスを使用していないことを示す SQL を発見しました。確認したところ、varchar 型のフィールドであることがわかりました。条件を使用して数値を渡しました。機密保持契約に違反する恐れがあるため、ここでは画像を投稿しません。同様の状況を再現して、皆さんに見ていただきたいと思います。

問題の再現

まず、効果を上げるために、USER_ID を varchar 型に設定し、一意のインデックスを追加したユーザー テーブル test_user を作成します。

テーブルtest_userを作成します(
  ID int(11) NOT NULL AUTO_INCREMENT、
  USER_ID varchar(11) DEFAULT NULL COMMENT 'ユーザーアカウント',
  USER_NAME varchar(255) DEFAULT NULL COMMENT 'ユーザー名',
  AGE int(5) デフォルト NULL コメント '年齢',
  COMMENT varchar(255) DEFAULT NULL COMMENT 'はじめに',
  主キー (ID)
  ユニークキー UNIQUE_USER_ID (USER_ID) BTREE 使用
)ENGINE=InnoDB デフォルト文字セット=utf8;

テーブルデータは以下のとおりです(データは前回のMySQL記事と同じデータを使用しています。MySQLはUNIONを使用して2つのクエリを接続し、ソートに失敗しますが、テーブル構造が異なることに注意してください)。

IDユーザーIDユーザー名コメント
1 111ハッピールーキー18今日はとても幸せです
2 222悲しい新人21今日は悲しい
3 333真面目な新人30今日はとても深刻だ
4 444ハッピールーキー18今日はとても幸せです
5 555真面目な新人21今日は深刻だ

次に次のSQLを実行します

EXPLAIN SELECT * FROM test_user WHERE USER_ID = 111;

与えられた説明は次のようになります。

id選択タイプテーブルパーティションタイプ可能なキーキーの長さ参照フィルター余分な
1単純テストユーザー全て5 where の使用

条件を引用符で囲んで次のように説明します。

EXPLAIN SELECT * FROM test_user WHERE USER_ID = '111';

この時点で、varchar 型フィールドは文字列としてクエリされたときにはインデックスを使用しますが、数値型としてクエリされたときにはインデックスを使用しないことがわかりました。

問題の拡大

質問は、フィールドが整数でインデックスがある場合、文字列でクエリを実行するときにインデックスは使用されないのでしょうか?練習すれば完璧になります。引き続きテストを続けましょう。

-- USER_IDの型を整数に変更する CREATE TABLE test_user (
  ID int(11) NOT NULL AUTO_INCREMENT、
  USER_ID int(11) DEFAULT NULL COMMENT 'ユーザーアカウント',
  USER_NAME varchar(255) DEFAULT NULL COMMENT 'ユーザー名',
  AGE int(5) デフォルト NULL コメント '年齢',
  COMMENT varchar(255) DEFAULT NULL COMMENT 'はじめに',
  主キー(ID)、
  ユニークキー UNIQUE_USER_ID (USER_ID) BTREE 使用
) ENGINE=InnoDB AUTO_INCREMENT=6 デフォルト CHARSET=utf8;
EXPLAIN SELECT * FROM test_user WHERE USER_ID = 111;
EXPLAIN SELECT * FROM test_user WHERE USER_ID = '111';

上記の 2 つのステートメントを実行した後、int 型フィールドは、文字列としてクエリされるか数値としてクエリされるかに関係なく、インデックスが作成されることがわかりました。

結論は

  1. 使用するフィールドが数値型の場合、引用符を追加するか追加しないか(SQLでは一重引用符と二重引用符は同じ効果があります)はインデックスの使用に影響しません。
  2. フィールドが文字列型の場合、インデックスは引用符なしのクエリには使用できませんが、引用符付きのクエリには通常どおりインデックスを使用できます。

まとめると、文字列型がインデックス化されない状況を回避するために、今後 SQL を書くときには引用符を追加するのが最善だと思います。より深い原則についてはさらに検討する必要があります。ご意見がありましたら、ぜひ議論してください。

これで、MySql 整数インデックスと文字列インデックスの無効化または暗黙的な変換に関するこの記事は終了です。MySql 整数インデックスと文字列インデックスの無効化の詳細については、123WORDPRESS.COM の以前の記事を検索するか、次の関連記事を引き続き参照してください。今後とも 123WORDPRESS.COM をよろしくお願いいたします。

以下もご興味があるかもしれません:
  • MySQLの驚くべき暗黙の変換
  • MySQL 5.6 の「暗黙的な変換」によりインデックスが失敗し、データが不正確になる
  • MySQLの暗黙的な変換について話す
  • MySQLの暗黙的な変換問題の解決
  • MySQL インデックス無効化の暗黙的な変換の問題

<<:  モバイルデバイス Web 開発における HTML ヘッドの書き方

>>:  nginxコンテナ設定ファイルの独立した実装

推薦する

面白いウェブサイトをデザインするための方法とテクニック(写真)

他の人から「つまらない」とか「時代遅れ」というフィードバックを受けて、それを変更しようとしたのに、更...

HTML テーブル マークアップ チュートリアル (16): タイトルの水平方向の配置属性 ALIGN

デフォルトでは、表のタイトルは水平方向に中央揃えされます。ALIGN 属性を使用して、タイトル テキ...

Linuxにグラフィカルインターフェースをインストールする方法

1. Linuxのインストール(rootユーザー操作) 1. vncserver をインストールしま...

Linux でディスクをマウントし、起動時に自動的にマウントするように設定する方法

皆さんの時間は貴重だと承知しているので、プロセス コマンドを直接書き留めておきます。設定できます。原...

MacOS Catalina アップグレード後の VMware ブラック スクリーン問題に対する完璧な解決策の詳細な説明

MacOS Catalina アップグレード後の VMware ブラック スクリーンに対する完璧なソ...

Apache SkyWalkingのセルフモニタリングを素早く有効にする方法を説明します

1. Prometheusテレメトリデータを有効にするデフォルトでは、テレメトリは次のように無効にな...

Linux C++ マルチスレッド同期の非常に詳細な説明

目次1. ミューテックス1. ミューテックスの初期化2. ミューテックスロックの関連特性と分類3. ...

Linux におけるゼロコピー技術の使用に関する簡単な分析

この記事では、Linux におけるいくつかの主要なゼロコピー テクノロジと、ゼロコピー テクノロジを...

Dockerの急速な拡張の高度な方法

1. コマンド方式作成された Swarm クラスターで nginx サービスを実行し、--repli...

CentOS 7 は Hadoop 2.10 の高可用性 (HA) をビルドします

この記事では、CentOS 7 で高可用性 Hadoop 2.10 クラスターを構築する方法を紹介し...

Dockerコンテナの構築と実行のプロセスの詳細な説明

イメージをプルし、コンテナを作成してコンテナを実行するだけです。 docker run -d --r...

初心者のためのWebページ作成: HTMLのハイパーリンクAタグの使い方を学ぶ

ハイパーリンク a タグはリンク ポイントを表し、英語の単語「anchor」の略語です。その機能は、...

...

Vue ページに img 画像を導入する方法

HTMLを学ぶとき、画像タグ<img>は画像を導入します <img src=&qu...