MySQLのインデックスについて質問です。
カーディナリティの低いものにインデックスをつけるべきではない、と考えていたのですが
カーディナリティが低くても、対象テーブルのレコードの分布に偏りがある場合はインデックスを貼ると効果がでるのでしょうか。
例えば、商品の在庫表などで
販売ステータスという列があり、ステータスは「未販売」「販売済み」という種類があったとします。
普通に考えれば、このステータスカラムにインデックスを付けることはカーディナリティの低いと思いますが
販売済みステータスは増え続けるはずですので、時を経るごとに未販売ステータスのレコードが極端に少なくなります。
この場合、インデックスを貼ることで高速化が図れるのでしょうか。
ご回答よろしくお願いします。
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。

回答5件
0
ベストアンサー
データ件数が膨大で、一方に絞り込んだデータ郡に対する検索の頻度が利用方法の大多数を占めるなら効果はあると思います。
sql
1SELECT * 2FROM item 3WHERE st = 2 /* 未販売 */ 4AND price > 1000
このようなSQL発行が多く、未販売が100件程度で販売済みが数百万件のような場合、st(未販売or販売済み)にindexがあればSQLの実行自体は高速化されるでしょう。
「未販売」と「販売済み」を選り分ける作業がindexによってほぼ無くなる程度まで軽減されるので、この作業のコストが高ければ高いほど(つまりレコード件数が多いほど)効果があります。
そして(上記の設定のように)その選り分ける作業こそがそのSQLのコストの大半だったなら、高速化率も高くなります。
しかしこのような場合は、まず販売済みの古いデータを定期的にバックアップに移して省くことを検討したほうが良いかもしれません。あまりにレコードが多いとデータ登録時のindex作成も負担になってくるためです。(データ件数が膨大ということは登録や更新も頻繁に行われるということですし)
追記
ところで上記のような例でpriceにもindexがあり、全体に対する「price > 1000」が「st = 2」よりも少ないと簡単に予測できる場合、オプティマイザは「price > 1000」を先に実行するプランを選択するかも知れません。そうすると「st = 2」のために極少数のレコードのソートで済みstへのindexにあるなしに関わらず実行速度が殆ど変わらなかった。ということもあるかも知れません。
以下の部分はコメントで指摘いただいた通り誤りで、極端に分布が偏った方を参照するのでない限りindexに意味は無いようです。
カーディナリティが低くても、対象テーブルのレコードの分布に偏りがある場合は
仮に偏りが無くても、また100:100万に対して100万の方を選択する絞込みだったとしても、ソートが必要になる時点でindexには意味が出てくるように思います。
そして絞込みや検索には大抵ソートが必要です。(たぶん)
カーディナリティが高い例えばユニークidのような要素だと、indexはその要素を条件にした結合などの操作にも威力を発揮します。しかしカーディナリティが低い要素では境界を発見するような操作にしか威力を発揮できないので、コストが同じな割りに用途が少なく効率が悪いということだと思います。
でも”その操作をこそメインに頻繁に行う”のであれば意味はあるんじゃないかな。。
投稿2016/08/04 11:20
編集2016/08/05 09:28総合スコア2068
0
カーディナリティが高かろうが低かろうが、外部キー制約をかける場合にはインデックスは必須となって、選択の余地はありません。
とりわけ、今回のような業務フラグ列の場合(本当にBOOLEANなどきっちりの型で入れる場合はともかく)、異常値の混入を防ぐために外部キー制約をかけておいたほうがいいのではないかと思いました。
投稿2016/08/04 14:05
総合スコア146544
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
今回のケースではインデックスは不得手なのではないかな思います。
更新を多く伴うテーブルのカラム(ステータスなので更新が多そうな気がする)にインデックスを張ると、
インデックス自体の更新も発生するため一般的には逆にパフォーマンスに悪影響が出る恐れも高いです。
takasima20さんのおっしゃる通り、
レスポンスが場合は先ずはボトルネックとなっている箇所を特定するのが重要です。
クエリに問題がありそうということでしたら、一度実行計画を見てみてはいかがでしょう?
###追記
分布に偏りがある方がインデックスの効果は高いですね。
素でボケをかましてました;
投稿2016/08/04 11:21
編集2016/08/04 11:28総合スコア1636
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
あんまり効果ないんじゃないかなあ。
もし、そういう需要があったとしてもインデックスで解決ってのはちょっと。
性能に不満があるということなら、まずは処理時間(所要時間)の分析から
はじめるのがふつうなんじゃ? 対策とるにも説得材料いりますよね。
投稿2016/08/04 10:35
総合スコア7468
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。

あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2016/08/05 01:03
2016/08/05 09:04
2016/08/05 09:05
2016/08/05 09:25
2016/08/05 09:56 編集
2016/08/05 10:07