• ベストアンサー

インデックスの一意な値の数について

インデックスを下記のように作成しているのですが、 MySQLはインデックスは同時に1つしか使用されないようなので どれを消そうか迷っています。 約177万件レコードがあるのですが、レコード数のうち 一意な値の数が何割以下ならインデックスを 張る意味がないといった基準はあるでしょうか? 一意な値の数 1.1772253(PK int型) 2.2338(idx int型) 3.1122(idx int型) 4.18(idx int型)

  • php4
  • お礼率42% (373/888)
  • MySQL
  • 回答数2
  • ありがとう数2

質問者が選んだベストアンサー

  • ベストアンサー
回答No.1

>MySQLはインデックスは同時に1つしか使用されないよう MySQLのバージョンは、何でしょうか? 当方、WindowsXP Home Editionで、MySQL 5.0.19-ntを使用していますが、「同時に1つのインデクスしか使われない」ということはありません。 実験的に、次の表定義&インデクス定義しました。 create table t1 (c1 int primary key, c2 char(1), c3 varchar(5), c4 timestamp, c5 text); create index t1ix2_4 on t1(c2,c3,c4); create index t1ix4 on t1(c4); create index t1ix5_4 on t1(c5(60),c4); 20000件のデータを格納し、以下のSQLのEXPLAINを確認しました。 explain select * from t1 where c1 between 1001 and 5000 and c2 between 'b' and 'f' and c4>='2007-11-15' ; 結果は、primary key、index t1ix2_4、t1ix4が使われています。 >約177万件レコードがあるのですが、レコード数のうち >一意な値の数が何割以下ならインデックスを >張る意味がないといった基準はあるでしょうか? B-TREEインデクスの話としては、「性別」の話がよく出ますね。2種類しか値がないなら、B-TREEインデクスを付ける効果はないと。 ただし、どのシステムでも当てはまるような基準といったものは、存在しません。 >一意な値の数 >1.1772253(PK int型) >2.2338(idx int型) >3.1122(idx int型) >4.18(idx int型) それぞれ単一列で構成するインデクスを、4本定義しているのですか? どういう条件指定をするのかや、order by、group by、distictを使ったりするのかが分からないと、適切なアドバイスはできません。 値の種類の話はひとまずおいてい置いて、単一列のインデクスが、本当に4本必要なのでしょうか? select * from t1 where c2 between a and b and c3>=d のc2とc3のように、必ず組み合わせて検索条件を指定するような場合は、(c2,c3)の複数列で構成するインデクスの方が効率的に利用できる場合が多いです。 また、インデクスは、order byやgroup by、distinctでも使用される場合があります。 select * from t1 where c2 between a and b order by c2,c3,c4 のようなSQLの場合、(c2,c3,c4)で構成するインデクスがあれば、検索条件で利用されるだけでなく、ソート抑止もでき、性能の向上が可能です。 インデクスの有効利用等に関し、マニュアル説明箇所を示しておきます。 バージョンが不明なので、下記はMySQL 4.1版です。 http://dev.mysql.com/doc/refman/4.1/ja/query-speed.html

php4
質問者

お礼

MySQLでは、1つのクエリを実行するとき、 1つのテーブルにつき1つのインデックスしか使用できないと ↓にあり、心配していました。http://labs.unoh.net/2007/06/mysql5.html  うーん。この情報は何を指しているのかわからなくなりました。 explainやってみたら、 確かにintersect(xx_id,xx_id) Using where というように複数のインデックスが使用されました。 インデックスの複合化については検討してみます。 ありがとうございます。

その他の回答 (1)

  • hrm_mmm
  • ベストアンサー率63% (292/459)
回答No.2

>1つのテーブルにつき1つのインデックスしか使用できないと↓にあり、心配していました。 >http://labs.unoh.net/2007/06/mysql5.html >うーん。この情報は何を指しているのかわからなくなりました。 ご呈示のサイト内をよく読めば、書いてありますが、MySQL4.0までの話です。 4.0までに比べ、4.1以降では、かなり機能拡張されています。index問題もその一つのようです。 ここの掲示板でもよく指摘されていますが、自分の利用しているMySQLのversionはしっかりと意識して使って下さい。

php4
質問者

お礼

すごく頭がすっきりしました! MySQL4.0の時に、分析ソフトを作っていたのですが いくらインデックスを張っても検索が遅く挫折したのですが バージョンによる機能不足が理由だったのですね・・ ありがとうございます。

関連するQ&A

  • (phpMyadminの)インデックスサイズの一意な値の数

    初心者です。 教えて頂けますか? 一つのフィールドにユニークのインデックスを付けたのですが (phpMyadminの)インデックスサイズの一意な値の数とありますが、 何を指すのでしょう?一意(ユニーク)の意味は分かるのですがいまいち意味が分かりません。 何の事でしょう? よろしくおねがいします。

  • コンポジット一意インデックスとは?

    趣味でPHPとMYSQLをいじってる大学生です。 先日はこちらで助けて頂いてとても助かりました。 ご返答いただきました皆様ありがとうございました。 単発の質問で申し訳ないのですが インデックスの指定をする際に疑問点がでてきたので 質問させて下さい。 タイトルにもあげたのですが、 コンポジット一意インデックスというのは インデックス(インデックスの名前はkeyの値) で複数カラムにインデックス指定するということだと思いますが 一意はユニークというのは 任意の挿入されるレコードは、2つの場合に限定すると 2のカラムを見ると他のレコードとかぶらないというか 要するに2つのフィールドをあわせて考えて、 ユニークであるという理解でよいでしょうか? 言葉がおもいつきませんが 例えば宝くじの  組  番号 購入者 ...etc  A組 0001 B組 0001 A組 0023 C組 ・・・ のようなデータを扱う際に 組と番号にコンポジット一意インデックスを割り振るといいというという理解でいいでしょうか? その理解が正しいか間違っているか? 教えていただけると幸いです。 そして、この理解で正しいのならば もしも 番号=0002 など、2つのフィールドのうち1つで検索した場合だとインデックスは役割を果たすのでしょうか? コンポじゃないと機能しないのか?ということです。 コンポじゃないと機能しないのであれば3つのインデックス つまり、(組,番号[コンポ]),(組),(番号) を作成するのが正しいのでしょうか? よろしくお願い致します。

  • MySQLのインデックスの使い方を教えてください。

    MySQLのインデックスの使い方を教えてください。 どうやら、検索性を上昇させるためのもののようですが… phpMyAdminで「構造」タブを開くと、【ユニーク】【インデックス】【全文】というアイコンがありますよね。 【ユニーク】を押すと 種別    :BTREE ユニーク  :はい 圧縮    :いいえ フィールド :(チェックを入れた各フィールドの名前) 一意な値の数:(チェックを入れたうち、なぜか最後のフィールドだけはレコード数が表示されるけど、他のフィールドは0になる。どれかひとつをキー的に扱えば充分ということでしょうか。どれでも大して変わらない?) 照合順序  :A 【インデックス】を押すと 種別    :BTREE ユニーク  :いいえ 圧縮    :いいえ フィールド :(チェックを入れた各フィールドの名前) 一意な値の数:0 照合順序  :A 【全文】を押すと 種別    :FULLTEXT ユニーク  :いいえ 圧縮    :いいえ フィールド :(チェックを入れた各フィールドの名前) 一意な値の数:0 となるようですが… (インデックス名は、チェックを入れたフィールドのうち先頭にあるものの名が勝手に採用されますが、後から変更できるみたいですね) 「複数のフィールドにいっぺんにチェックを入れてからアイコンを押す」のと、「ひとつのフィールドずつアイコンを押す」ので結果が違って、なんだか気持ち悪いです。 バラバラのインデックスを作るのと、ひとつのインデックスにまとめるのでは、どう違うのでしょう? 普通はどうするものでしょうか? 例えば no ryaku  cctld  ei   seisiki 1 日本   .jp  japan  日本国 2 アメリカ .us  U.S.A  アメリカ合衆国    3 中国   .cn  China  中華民主主義人民共和国 のように、すべて(あるいはほとんど)のフィールドが一意である場合の例が知りたいです。

    • ベストアンサー
    • MySQL
  • postgres table作成時にindex付与

    MySQLでは以下のようにテーブル作成時にインデックス付与ができます。 CREATE TABLE test ( a int(11) NOT NULL DEFAULT '0', b int(11) DEFAULT NULL, PRIMARY KEY (a), KEY test_idx (b), -- ★インデックス その1 KEY test_idx2 (a) -- ★インデックス その2 ); ポスグレではできませんか?

  • インデックスの作り方

    MySQL4.1.19を使っているのですが、ユニークなインデックスの作り方で困っています。 例えば、 create table dttest ( a int NOT NULL , b int NOT NULL , c int NOT NULL , d int NOT NULL , CONSTRAINT PK_dttest PRIMARY KEY ( b ) ) type=InnoDB; というテーブルがあったとして、 aフィールドはユニークのインデックスを作り cフィールドは、重複可能なインデックスを作りには どうすればよいのでしょうか? 初歩的な質問で申し訳ありませんが、 よろしくお願いします。

    • ベストアンサー
    • MySQL
  • 大きいデータ数のテーブルに対するインデックス作成

    mySQL server 5.1 でのindex作成について質問です かなり大きいデータ数(1000億)のテーブルを扱う必要があり検索速度向上のためにindexを作成しようとしています。テーブルのdouble型のカラムに対してインデックス作成コマンドを入力しましたが(create index)、数日経ってもまだインデックス作成が終わりません。長すぎて何か問題でも起きているのでは、と思ってのですが同様の形式のサイズの小さいデータベースに対して同様の処理を行うと問題なく終わります。 なんらかの方法でインデックス作成のスピードを上げることは可能でしょうか?たとえばint型のデータ型に変換するとスピードが向上するなどはあるでしょうか?

    • ベストアンサー
    • MySQL
  • インデックスを張るべき項目について

    20万件レコードのあるテーブルに、インデックスを張ると INSERTが遅くなるので、WHERE句で検索する項目のどれに インデックスを張るか悩んでいます。 インデックスはパターンが多い程、張った場合に 検索速度が向上すると理解しているのですが正しいでしょうか? であれば、下記1.だけは貼ろうと思っているのですが・・ 1.カラムに入るデータが殆どバラバラのVARCHAR(30) 2.カラムに入るデータは10万パターンのINT型 3.カラムに入るデータは1万パターンのINT型 4.カラムに入るデータはdatetime型 インデックスを張る事でINSERT速度が何%ぐらい下がるでしょうか? よろしくお願いします。

    • ベストアンサー
    • MySQL
  • phpMyAdminのテーブル構造画面のインデックスについて

    phpMyAdminのテーブル構造画面のインデックスについて 宜しくお願い致します。 MySQL5.0.22を使用しております。 phpMyAdminは2.7.0を使用しております。 phpMyAdminのテーブル構造画面で インデックスサイズの「一意な値の数」が、画面を更新する度に変わるんですが、なぜでしょう? 原因がよくわからないのですが、現在作っているシステム上は何も不具合が出ておりません。 原因に心当たりがございましたら、教えて下さい!

    • ベストアンサー
    • MySQL
  • インデックスがすぐに壊れます…

    テーブル内の1フィールドにインデックスを設定していますが、内容が頻繁に更新されるせいか1日前後でインデックスが破損し、テーブルへのアクセスができなくなって困っています。 以下、詳細な状況です。 ------------------------------------------ (1)該当テーブルのレコード数は、約16,000,000件 (2)インデックスは[レコード更新日時]フィールドに設定しています。 (3)15分おきにデータの自動更新を行い、数百~数千件のレコードが更新されます。 その際、当然ながら[レコード更新日時]フィールドも更新されます。 (4)1日~2日に1度の割合で(3)の自動更新処理が異常終了します。 SQLのエラーコードはまちまちですが、重要度は決まって20前後の深刻なレベルです。 (5)(2)のインデックスを削除→再作成すると、(3)の自動更新処理は正常に行える (6)以下、(3)~(5)の繰り返し ------------------------------------------ 16,000,000件のうちの数千件といえば、0.1%にも満たない量です。そのために頻繁にインデックスの更新をしているうちにファイルがおかしくなるのでしょうか? (ひょっとしたら、インデックスの更新が完了しないうちに次の自動更新処理が実行されているのかもしれません) 同様のケースをご存知の方、いらっしゃいましたらどのように解決したかを教えてください。

  • 配列のインデックス番号を返したいが

    インデックス番号を返したい x[0]=1 x[1]=2 x[2]=3 x[3]=3 x[4]=5 の場合で探す(返す)値を3とした場合⇒2,3と値が返るようにしたい import java.util.*; class Test7_23 { static int[] arraySrchIdx(int[] a,int x){ int idx = 0; for(int i=0;i<a.length;i++){ //A if(a[i]==x){ a[i] = i; idx++; } else{ a[i] = 0; } } for(int i=0;i<a.length;i++) //B System.out.println(a[i]); int[] b = new int[idx]; for(int i=0;i<a.length;i++){ if(a[i] != 0) for(int j=0;j<idx;j++) b[j]=a[i]; } for(int i=0;i<idx;i++) System.out.println("b["+i+"]="+b[i]); return b; } public static void main(String[]args){ Scanner std = new Scanner(System.in); System.out.print("配列の要素数は:"); int n = std.nextInt(); int[] x = new int[n]; for(int i=0;i<n;i++){ System.out.print("x["+i+"]="); x[i] = std.nextInt(); } System.out.print("探す値:"); int a = std.nextInt(); int[] b = arraySrchIdx(x,a); for(int i=0;i<b.length;i++){ System.out.println(b[i]); } } }