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

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

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

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

Q&A

解決済

2回答

421閲覧

MySQLに関して、インデックスの機能を確認したいです

yakan

総合スコア19

MySQL

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

0グッド

0クリップ

投稿2020/07/01 04:18

編集2020/07/01 04:31

###知りたいこと
インデックスについて確認させていただきたいことがございます。

仮にインデックスを次のように3つセットした場合ですが、

CREATE TABLE search_cache ( ID INT(10) UNSIGNED NOT NULL AUTO_INCREMENT, service_id TINYINT(1) UNSIGNED NOT NULL, q VARCHAR(100), color VARCHAR(10), updated_at DATETIME(6) NOT NULL, PRIMARY KEY (ID), # インデックスをセット INDEX idx_search_cache_01(service_id), INDEX idx_search_cache_02(q), INDEX idx_search_cache_03(color) );

この場合、次のSELECTでインデックスは効かないのではないでしょうか?

sql

1SELECT * 2FROM cache_datas 3WHERE service_id=1 AND q='りんご いちご' AND color='red'

###なぜこう考えたのか
インデックスは
idx_search_cache_01 (service_idが対象カラム)
idx_search_cache_02 (qが対象カラム )
idx_search_cache_03 (colorが対象カラム)
という3つでセットしています。

WHEREの最初にservice_idを指定した場合、その時点でまず、検索対象データはidx_search_cache_01となりますよね。

このidx_search_cache_01に対しさらにAND q='りんご いちご'と指定していますが、idx_search_cache_01のインデックスの中にはqに対するインデックスはありませんから、idx_search_cache_01の中ではqの並び順は不明瞭ですよね。

そうであれば、qに対してセットしたidx_search_cache_02は、上記SELECTのように

一番目にidx_search_cache_01を指定したSELECT
(つまり一番目にWHERE service_id=1と指定したSELECT)

では効かないのではないかと考えたのですが…

###対策
上記の考え方があっていれば、ひょっとして、複合インデックスというのはこのための機能なのでしょうか?

つまりインデックスは3つでなく次のように1つに複合して、
INDEX idx_search_cache_01(service_id,q,color)
こうすることではじめて、上記SELECTでもインデックスが効くという仕組みですか?

###さらなる疑問
上記の考え方と対策が正しい場合ですが、そうすると検索のパターンが複数ある場合、そのパターンだけ複合インデックスを貼るということになるのでしょうか?

たとえばSELECTしたいパターンとして次の【A】と【B】2つがあった場合

sql

1# パターン【A】 2SELECT * 3FROM search_cache 4WHERE service_id=1 AND q='りんご いちご' AND color='red' 5 6# パターン【B】 7SELECT * 8FROM search_cache 9WHERE service_id=1 AND color='red'

この場合は複合インデックスも次のように貼るということになるのでしょうか?
【A】のためのインデックス → INDEX idx_search_cache_01(service_id,q,color)
【B】のためのインデックス → INDEX idx_search_cache_02(service_id,color)

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

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

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

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

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

guest

回答2

0

ベストアンサー

FROM句の一つのテーブルに対して使用されるインデックスは一つです。
また、インデックスを使用するかどうかは、統計情報を元にオプチマイザーが判断します。

マルチカラムインデックスで項目が全て揃っているからと言って使用されるわけでもありません。
項目の並びが逆の場合に非効率と判断されて使用されない事もあります。

質問の例で使用されないのは、総じて件数が少ないから、全表検索が効率的とオプチマイザーが判断したのでしょう。

検索のパターンが複数ある場合、そのパターンだけ複合インデックスを貼るということになるのでしょうか?

SQLが違うなら、当然適切なインデックスも変わります。
但し、「大は小を兼ねる」事が出来ますので、兼用できるようにインデックスを構成します。
項目の並びは、カーディナリティの低いものから並べるのがコツです。

投稿2020/07/01 05:17

編集2020/07/01 05:58
sazi

総合スコア25327

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

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

yambejp

2020/07/01 05:28

MySQLの場合、使用するインデックスを強制的に指定ができますね ただおっしゃるとおりオプティマイザが選ぶインデックスが効率的だとは思いますが。
sazi

2020/07/01 05:52

他のDBMSでもインデックスの指定はできますけど、余程でない限り使わないですね。
tacsheaven

2020/07/01 06:51

もう10年以上昔の話ですが、下手にインデックス使う/使わないで処理時間が大きく食い違うのを避けるため、「full scan ヒント句書け」ってのを DBA に言われたことはあります(w まあ母数が億のオーダーならそうもなりますね(w ※バッチ処理(しかも後続がいる)だったので、処理時間が極端に増減されるよりはマシなのです
sazi

2020/07/01 07:25

遅い方に平準化ですね。 開発技量にムラがあると、DBAとしてはそうも言いたくなるんでしょうね。
tacsheaven

2020/07/01 08:02

開発技量と言うより、システムの(ハード的な部分も含めての)性能限界を前提として、とにかく規定時間に終ることを優先させたらそうなったという感じですね。早く終る分には後続の開始を待つだけですが、遅く終ると後続が遅くなって全処理終了のタイムリミットを超過してしまいかねないので。 ※で、なんとか3時間で終らせる目処が立ったら、「後続がどうしても遅いので処理時間を30分繰り上げられない?」とされたという(w
sazi

2020/07/01 08:10 編集

full scanに対応したインデックスを作成しかつfull scanを指定するって事ですか。 その上、後から早くしろって言う(w そのDBAが手抜きしたとしか思えませんね。
tacsheaven

2020/07/01 09:39

逐次処理の方で必要なインデックスはあるけど、バッチでそれを使うとかえって遅くなるから full scan 固定で、って話でしてね。full scan なら対象のレコード数の想定からだいたい性能が見積もれるので。 でまあ……後から早くするのは DBA のせいというより全体の設計の話で。どうにか頑張って2時間ぐらいまで処理性能を上げて、余裕を作りましたけどね……処理の一部をオンメモリ化するとか苦労させられました。まだオンメモリDBのオプションがない時代だったんで、フルスクラッチですわ(汗 なおそのときに DBA の手が足りないからと言うことで、なぜか自分が(チーム内どころか他チームまで)チェックとチューニングをする羽目になったという苦い思い出が(汗
sazi

2020/07/01 13:20 編集

夜間バッチが1日じゃ終わらないというのは、あるあるですね。 チューニングの際に、試行錯誤で無駄と思える処理が性能に貢献するというのを何度か経験しました。 何れ改善されるだろうから無駄な知識でしかないですけどね。
guest

0

3カラムにまたいだ検索が前提なら、3カラムを複合インデックスで貼ってください

投稿2020/07/01 04:24

yambejp

総合スコア116724

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

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

yambejp

2020/07/01 04:25

q='りんご いちご'も微妙ですね。 完全一致でその内容がかかれているならOKですが、一部一致など 考えるとデータの羅列は検索しづらいです
yakan

2020/07/01 04:33

>3カラムにまたいだ検索が前提なら、3カラムを複合インデックスで貼ってください えーっと、それは「対策」にある通りですが、「なぜこう考えたのか」があっているからという意味ですか?
yakan

2020/07/01 04:33

>q='りんご いちご'も微妙ですね。 qは検索ワードを保存するカラムで、ソートされているので完全一致でいいかと思っています。
yambejp

2020/07/01 04:56 編集

別に3カラム複合で2カラムしか検索条件に使わなくてもインデックスは有効です
yakan

2020/07/01 05:06

ありがとうございます
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問