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コンテナ設定ファイルの独立した実装

推薦する

Navicat 接続 MySQL エラーの説明分析

目次環境仮想マシンバージョンMySQL バージョン事前準備MySQLの実行ステータスを確認するルート...

HTML webpackプラグインの使用に関する簡単な分析

html-webpack-pluginプラグインを使用してページを開始すると、htmlページをメモリ...

Dockerコンテナを外部IPとポートにバインドする方法

Docker を使用すると、外部からコンテナにアクセスしたり、コンテナを相互接続したりすることで、ネ...

Ubuntu 18.04にPython仮想環境をインストールする

Ubuntu 18.04 を使用する Python 開発者向けの参考資料です。 1. Ubuntu ...

nginx ssl を設定して https アクセスを実装する手順 (初心者向け)

序文サーバーを展開した後、私は大きな喜びを感じながら自分の Web サイトにアクセスし、見たものすべ...

mysql5.6 マスタースレーブ設定と非同期の問題の詳細な説明

目次1. MySQL マスタースレーブレプリケーションの原理2. MySQLのコンパイルとインストー...

この構成ファイルの排他ロックに失敗したという VMware 仮想マシンのプロンプトの解決方法

VMware が異常シャットダウンした後、再起動すると「この構成ファイルを排他的にロックできませんで...

nginx の http リクエスト処理の各段階の詳細な分析

nginx の HTTP モジュールを作成する場合、リクエスト開始時のアクセス許可の有無、コンテンツ...

Vueは開始時間と終了時間の範囲クエリを実装します

この記事では、Vueで開始時間と終了時間の範囲を照会する方法を参考までに紹介します。具体的な内容は次...

Vueはechart円グラフの凡例のパーセンテージを表示するメソッドを実装します

この記事では主に、echart を使用してパーセンテージを表示する Vue の円グラフデータ部分を紹...

portainer を使用してリモート docker に接続するチュートリアル

Portainer は、Docker ホストと Docker Swarm クラスターの管理に使用でき...

CSSスコープ(スタイル分割)の使用の概要

1. CSSスコープの使用(スタイル分割) Vue では、CSS スタイルを現在のコンポーネントでの...

Centos7 環境でソースコードから mysql5.7.16 をインストールする方法の詳細な説明

この記事では、centos7 環境でソース コードから mysql5.7.16 をインストールする方...

HTML ヘッドタグの詳細な紹介

HTML のヘッド部分には、ブラウザによる Web ページのレンダリングや SEO などに関連するタ...

流星効果を実現する JavaScript キャンバス

この記事では、JavaScriptキャンバスで流星の特殊効果を表示するための具体的なコードを参考まで...