質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

SQL

SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

MariaDB

MariaDBは、MySQL派生のオープンソースなリレーショナルデータベースシステムです。 また、MySQLとほぼ同じデータベースエンジンに対応しています。

Q&A

解決済

2回答

6694閲覧

複合インデックスは1つのwhereでも効果がありますか?

daiki002

総合スコア68

MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

SQL

SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

MariaDB

MariaDBは、MySQL派生のオープンソースなリレーショナルデータベースシステムです。 また、MySQLとほぼ同じデータベースエンジンに対応しています。

0グッド

0クリップ

投稿2020/08/11 15:41

編集2020/08/11 16:42

前提

first_nameとlast_nameを1つとしてインデックスを作成しています。

sql

1CREATE TABLE `users` ( 2 `id` INT(11) NOT NULL AUTO_INCREMENT, 3 `first_name` VARCHAR(16) NOT NULL COLLATE 'utf8_general_ci', 4 `last_name` VARCHAR(16) NOT NULL COLLATE 'utf8_general_ci', 5 `age` INT(11) NOT NULL, 6 PRIMARY KEY (`id`) USING BTREE, 7 INDEX `first_name_last_name` (`first_name`, `last_name`) USING BTREE 8) 9COLLATE='utf8_general_ci' 10ENGINE=InnoDB 11AUTO_INCREMENT=1; 12 13 14INSERT INTO `feed_router`.`users` (`id`, `first_name`, `last_name`, `age`) VALUES ('1', 'tarou1', 'tanaka', '1'); 15INSERT INTO `feed_router`.`users` (`id`, `first_name`, `last_name`, `age`) VALUES ('2', 'tarou2', 'tanaka', '2'); 16INSERT INTO `feed_router`.`users` (`id`, `first_name`, `last_name`, `age`) VALUES ('3', 'tarou3', 'tanaka', '3'); 17

聞きたいこと

SQL1はwhere句でfirst_name, last_nameを指定しているので作成済みのインデックスの通りindexが利用されています。
SQL2はwhere句でfirst_nameのみを指定しているのですがpossible_keysがあるのでindexが利用されているように見ます。

Q1. 複合インデックスを作っている場合、where句で1つだけを指定してもインデックスが効きますか?
(B木で作成されるインデックスは複数列専用では無く、1つだけの場合も考慮された構造になっているのでしょうか?)
Q2. 複合インデックスがあるところに対して更に1つだけのインデックスを作る必要はありますか?

SQL1

SQL

1select * from users where first_name = 'tarou1' and last_name = 'tanaka' 2explain select * from users where first_name = 'tarou1' and last_name = 'tanaka' 3explain結果省略)

SQL2

SQL

1select * from users where first_name = 'tarou1' 2explain select * from users where first_name = 'tarou1'

idselect_typetabletypepossible_keyskeykey_lenrefrowsExtra
1SIMPLEusersreffirst_name_last_namefirst_name_last_name50const1Using index condition

補足情報(FW/ツールのバージョンなど)

  • 10.2.12-MariaDB

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

Q1. 複合インデックスを作っている場合、where句で1つだけを指定してもインデックスが効きますか?

そのインデックスの先頭の項目が条件であれば、適用されます。

Q2. 複合インデックスがあるところに対して更に1つだけのインデックスを作る必要はありますか?

複合インデックスの先頭を含まない条件の場合は、その条件項目から始まるインデックスが必要です。

※where条件の記述順序は関係ありません。

投稿2020/08/11 16:24

編集2020/08/11 16:25
sazi

総合スコア25173

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

daiki002

2020/08/11 16:49 編集

ご回答ありがとうございます。 確かに先頭を含まない条件の場合インデックスが効いてない事が確認できました。 例. select * from users where last_name = 'tarou1' 理解が深まりました。ありがとうございます。
daiki002

2020/08/11 16:51 編集

すみません更に以下の3つでインデックスを作成して確認してみた所、先頭を含まない場合でもインデックスが使われているように見えました。 INDEX `first_name_last_name_age` (`first_name`, `last_name`, `age`) USING BTREE explain select * from users where last_name = 'tarou1' and age = 1 possible_keys: NULL key: first_name_last_name_age key_len: 104 ref: NULL rows: 3 Extra: Using where; Using index また、先程はインデックスが効かなかった以下のSQLも今はインデックスが効いています。 select * from users where last_name = 'tarou1' 3つ以上の複合インデックスの場合は先頭を含まない場合でもインデックスが効くのでしょうか?
sazi

2020/08/12 00:11 編集

ref=Nullなのでwhere条件が理由でインデックスが使われた訳ではなさそうです。 理由は分かりかねます。 検証データが少なすぎるからかもしれません。 > 先程はインデックスが効かなかった以下のSQLも今はインデックスが効いています クエリーキャッシュは都度クリアして検証していますか?
daiki002

2020/08/13 04:19

RESET QUERY CACHE; を使用してクエリーキャッシュを削除して同様の確認をしましたがUsing indexと表示される為、今回の環境ではキャッシュによらずインデックスが使われている状況と思われます。
sazi

2020/08/13 04:29

では、後はデータ件数をそれなりに用意してみる事ですね。
daiki002

2020/08/20 01:23

1,000万件の適当なデータを入れたテーブルで試した所おっしゃる通りの結果となりました。 ※explainの結果で「possible_keysがnull」「keyがfirst_name_last_name_age」と表示される件は変わらないままでした。詳細不明です。 しかし、明らかに結果が返ってくるまでの時間に違いがありました。
guest

0

Using index condition

だから、インデックスが有効です。
郵便番号データダウンロード などまとまったデータを使って実感を実測されては?

投稿2020/08/11 15:49

Orlofsky

総合スコア16415

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問