MySqlの整数インデックスと文字列インデックスの失敗または暗黙の変換問題
問題の概要
今日、職場でDBAが突然、SQLの中にインデックスを経由しない暗黙の変換があることを示す部分を発見しました。調べてみると、それはvarchar型のフィールドで、条件を使って数値を渡していました。NDAに抵触する恐れがあるので、ここに画像は載せませんが、似たような状況を再現して見ます。
問題の再現
まず、ユーザー・テーブル test_user を作成し、USER_ID を varchar に設定し、効果的なユニーク・インデックスを作成します。
CREATE TABLE test_user (
ID int(11) NOT NULL AUTO_INCREMENT,
USER_ID varchar(11) DEFAULT NULL COMMENT 'user account',
USER_NAME varchar(255) DEFAULT NULL COMMENT 'User Name',
AGE int(5) DEFAULT NULL COMMENT 'Age',
COMMENT varchar(255) DEFAULT NULL COMMENT 'Profile',
PRIMARY KEY (ID)
UNIQUE KEY UNIQUE_USER_ID (USER_ID) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
テーブルのデータは以下の通りです(へへっ データは前回のMysqlの記事をそのまま使用しています)。 MySQLがUNIONを使って2つのクエリを結合する際のソート失敗について (同じデータですが、テーブルの構造が違うので注意してください)
<テーブル ID USER_ID USER_NAME 年齢 コメント 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;
与えられた解釈は次のようなものであることがわかった。
<テーブル イド セレクトタイプ テーブル パーティション タイプ 可能なキー キー キー_レン レフ 列 フィルタリング おまけ 1 シンプル テストユーザー すべて 5 使用場所条件を引用符で囲んで、次のように説明します。
EXPLAIN SELECT * FROM test_user WHERE USER_ID = '111';
この時点で、varchar型のフィールドは文字列としてクエリされた場合はインデックスを使用し、数値型としてクエリされた場合は使用しないことがわかります。
質問の引き出し
そこで問題なのは、フィールドが整数でインデックス化されている場合、文字列としてクエリしたときにインデックス化されないか、ということです。続けてこれを検証してみましょう。
-- Change the type of USER_ID to an integer
CREATE TABLE test_user (
ID int(11) NOT NULL AUTO_INCREMENT,
USER_ID int(11) DEFAULT NULL COMMENT 'user account',
USER_NAME varchar(255) DEFAULT NULL COMMENT 'User name',
AGE int(5) DEFAULT NULL COMMENT 'Age',
COMMENT varchar(255) DEFAULT NULL COMMENT 'Profile',
PRIMARY KEY (ID),
UNIQUE KEY UNIQUE_USER_ID (USER_ID) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8;
EXPLAIN SELECT * FROM test_user WHERE USER_ID = 111;
EXPLAIN SELECT * FROM test_user WHERE USER_ID = '111';
上記の2つのステートメントを実行した結果、int型のフィールドは文字列としてクエリされても数値型としてクエリされてもインデックスが作成されることがわかりました。
結論
- 使用するフィールドが数値型の場合、引用符を追加してもしなくても(SQLでは一重引用符と二重引用符で同じ効果が得られます)、インデックスの使用には影響しません。
- フィールドが文字列型の場合、引用符なしのクエリはインデックスを使用できず、引用符ありのクエリは通常通りインデックスを使用できます。
要約すると、私はあなたがこの文字列型は、状況のインデックスに行かない避けるために引用符を追加するすべての注意を払うときに、将来的にSQLを記述する方が良いと思う、深い原則は、もう少し掘りする必要があります、任意のコメントを議論することができる場合。
MySql整数インデックスと文字列インデックスの障害または暗黙の変換問題についてのこの記事は、このに導入され、より関連するMySql整数インデックスと文字列インデックスの障害の内容はBinaryDevelopの以前の記事を検索してくださいまたは次の関連記事を閲覧し続けるあなたは将来的にBinaryDevelopをよりサポートします願っています!.
関連
-
ジョイントインデックスのためのmysqlの条件とインデックスが失敗するための条件
-
SQL集計、グループ化、ソート
-
MySQLインデックスベースストレステストの実装
-
MySql認証ベースのvsftpd仮想ユーザー
-
MySQLによる既存テーブルのパーティショニングの実装
-
MySQLデータベースで数百万件のデータを10秒間で挿入
-
[解決済み】MySQLで「すべての派生テーブルは独自のエイリアスを持つ必要があります」というエラーは何ですか?
-
[解決済み】ValueError: 値の長さがインデックスの長さと一致しない|Pandas DataFrame.unique()
-
SQLステートメントエラーです。オペランドには 1 つのカラムを含める必要があります [括弧を追加せずに複数のフィールドをクエリする
-
SQLException。オペランドは1列でなければなりません。
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
SQL基本クエリステートメント
-
MySQLはこのようなUpdateステートメントを書くべきではありません
-
MySQLインストールチュートリアル(Windows用)詳細
-
Mysqlデータベースの手動および定期的なバックアップ手順
-
SpringBootのMySQLへの接続は、バックエンドのインターフェイスの操作方法を書き込むためのデータを取得するために
-
[解決済み】MySQL エラー 1093 - FROM 句で更新のターゲット テーブルを指定できません。
-
[解決済み] ユニークなテーブル/エイリアスではない
-
[解決済み】文字列からuniqueidentifierに変換する際に変換に失敗する - 2つのGUIDの場合
-
[解決済み] SQLエラー。ORA-01861:リテラルは、フォーマット文字列01861に一致しません。
-
'INSERT文はFOREIGN KEY制約「FK_TourismReservation_Users」と競合していました。その