- 締切済み
インデックスを用いたbetween検索について
Cで1~360000までのランダムな整数の列(col1)を含む100万件のデータを作成し(50MB弱)、 create table table1(・・・, col1 integer not null, ・・・); で作ったテーブルにload data infile文で挿入し、 create index index1 on table1(col1); でインデックスを作成しました。 select * from table1 where col1 between 1000 and 2000; といったような検索(約2500件ヒット)をしたいのですが、この検索ではインデックスを作らないテーブルのほうが速く検索できてしまいます。 select * from table1 where col1 between 100 and 200; のような検索(約250ヒット)ではインデックスの効果があり、高速検索ができますが。 環境はMySQL-5.0.26、ノートPC(256MB)、Fedora Core5、設定ファイルはMy-large.cnfを、ほぼそのまま使用しています。 上記のような少し大きめの検索範囲でもインデックスを用いた検索を改善する方法をご教授お願いします。何かのパラメータが決定的に足りないと思うのですが。
- downboy
- お礼率48% (12/25)
- MySQL
- 回答数2
- ありがとう数1
- みんなの回答 (2)
- 専門家の回答
みんなの回答
- t_nojiri
- ベストアンサー率28% (595/2071)
では、もう既に検索されてるかも知れませんが、チューニングパラメタが出ている参考URLを。 my.cnfファイルの下記パラメタを最適化しましょう。 >set-variable = key_buffer=256M #メモリに余裕がある場合に指定。検索に使われるインデックスをバッファに保存する際のメモリサイズ >set-variable = max_allowed_packet=1M #入力データ保持のための最大バッファサイズ。画像など、大きなデータ挿入でこの制限に引っ掛かる可能性がある
- t_nojiri
- ベストアンサー率28% (595/2071)
ヒット件数多い場合、取り出し結果をメモリ上に展開出来きらないと遅くなります。 っていうか、こういう場合カーソル等作って1件ずつ処理していくような気がしますけど。
補足
早速のご回答ありがとうございます。 最終的な目的からこのような検索方法になってしまうのです。 そのメモリを増やすパラメータはないのでしょうか。 実は他にもっと高性能のPCなどでチャレンジしていますが、どれも同じような結果になってしまうのです。 PostgreSQLで同様の検索を行なうと設定は変えないままでうまくいくのですが。
関連するQ&A
- DateTime型の検索
お世話になっております。 質問内容は基本的な事かもしれませんがご容赦ください。 あるテーブルにDateTime型のフィールドがあり、Insertした日時を保存しています。 このフィールドに対して、日付のBETWEENや時間のBETWEENで検索かけるにはどうしたら良いのでしょうか。 例えば、 時間は未指定だけど、1月1日から1月31日までのデータを検索 SELECT * FROM table WHERE insertDT BETWEEN '01-01' AND '01-31' 日付は不明だけど、7:00から12:00までのデータを検索する等です。 SELECT * FROM table WHERE insertDT BETWEEN '07:00' AND '12:00' これら試しましたが、正常な結果が得られず困っています。 不明な部分の代替文字でもあるのでしょうか。 SELECT * FROM table WHERE (insertDT >= '07:00' AND insertDT <= '12:00') これも試しましたがやはりダメでした。 どなたかご教示の程、よろしくお願い致します。
- ベストアンサー
- MySQL
- date型でのbetweenについて教えてください。
皆様、新年明けましておめでとうございます。 早速ですが、date型でのbetweenについて教えてください。 SQL文 SELECT * FROM test WHERE date between date '2007-12-01' and date '2007-12-31' を発行すると、2007-12-31のレコードがあるのに該当しません・・・ 試しにSQL文を SELECT * FROM test WHERE date between date '2007-12-01 00:00:00' and date '2007-12-31 23:59:59' としても2007-12-31のレコードは検索されません・・・ SQL文を SELECT * FROM test WHERE date between date '2007-12-01' and date '2008-01-01' にすると2007-12-31が該当するのですが、 SELECT * FROM test WHERE date between date '2007-12-01' and date '2007-12-31' では2007-12-31のレコードは該当しないものでしょうか?? select * from test where num between 10 and 100 とした場合では、num が 10 ~ 100 のものが問い合わされますよね?? date型になるとこうならないのでしょうか?? よろしくお願いします。
- ベストアンサー
- PostgreSQL
- 検索条件について
サーバ上にある以下のようにLOAD DATAでデータベースに登録し LOAD DATA INFILE "/home/abc/test001.csv" INTO TABLE test FIELDS TERMINATED BY ','; ENCLOSED BY '"'; 登録することはできたのですが個々テーブル毎では検索できますが 複数のテーブルで検索するとうまく検索できません。 【個々のテーブルは問題なし】 select * from abc where xyz=12345; select * from 123 where xyz=12345; これですと問題なく検索がヒットします。 【複数のテーブルで検索するとうまくいかない】 select * from abc,123 where abc.xyz=123.xyz; これですと検索してもヒットしません。 ちなみにabcのxyzにある項目を「'」で括ると検索できませんでした。 データは"1","12345"でセットしています。 LOAD DATAのやり方が悪いのでしょうか? どなたか教えていただけませんでしょうか。
- 締切済み
- MySQL
- 複数のindexについて
CREATE TABLE `test` ( `id` INT(8) , `num` INT(8) , 他多数 (省略) ) このようなテーブルがある場合、以下の2種類のインデックスのつけ方にどのような違いがあるのでしょうか? phpmyadminで確認すると、(1)はインデックスが合体しており、(2)はインデックスが個別に分かれています。 (1) ALTER TABLE `test` ADD INDEX ( `id` , `num` ) (2) ALTER TABLE `test` ADD INDEX ( `id` ) ALTER TABLE `test` ADD INDEX ( `num` ) ちなみに、以下のようなSELECT文を用いる場合には、どちらのインデックスが適していますか? SELECT * FROM test WHERE id='●' and num > '△' ( mysql5,MyISAM )
- ベストアンサー
- MySQL
- 単一行副問合せにより2つ以上の行が返されます。エラーになります。
単一行副問合せにより2つ以上の行が返されます。エラーになります。 お世話になります。 下記SQLを実行するとエラー”単一行副問合せにより2つ以上の行が返されます。” になってしまいます。 ご教授お願いします。 table1のcol01にtable2のcol01を table1のcol02にtable2のcol02を table2のcol03が3、table2のcol05が5で且つ table1のcol06とtable2のcol06が一致する場合に 変更したく下記SQLを作成しました。 update table1 set (col01,col02) = (select col01,col02 from table2 t2,table1 t1 where t2.col03 = 3 and t2.col05 = 5 and t2.col06 = t1.col06) where t1.col06 in (select col06 from table2); 以上 よろしくお願いします。
- ベストアンサー
- Oracle
- betweenで境界値が取得できない。
連番の歯抜け値を取得するSQLを作りたいと思っています。 例えば、カラムAに、1,2,3,5,6,7,9,10(4と8が抜けている) と数値の入っているテーブルAがあるとします。 これに対して、 SELECT MIN(カラムA + 1) FROM テーブルA WHERE (カラムA + 1) NOT IN (SELECT カラムA FROM テーブルA) とSQLを投げた場合、4が取得できます。 これにbetween句を付与したいのですが、そうすると境界値が なぜか取れなくて困ってます。 具体的には、 SELECT MIN(カラムA + 1) FROM テーブルA WHERE (カラムA + 1) NOT IN (SELECT カラムA FROM テーブルA) AND BETWEEN 8 AND 10 とした場合、NULLが返ってきてしまいます。 普通、BETWEENは境界値も対象になるはずですが、何故このような 結果になってしまうのでしょうか? 修正点をご教授いただけないでしょうか? 宜しくお願いします。
- ベストアンサー
- SQL Server
- 最適なインデックス作成
いつもお世話になってます。 下記のSQLがあるとします。 SELECT A.COL3, A.COL4, B.COL5, SUM(A.COL6) -- (5) FROM TABLE1 A INNER JOIN TABLE2 B ON A.COL1 = B.COL1 -- (2) WHERE -- (1) A.COL1 = '1' AND A.COL2 = '2' GROUP BY A.COL3 ,A.COL4 -- (3) ORDER BY A.COL3, A.COL4 -- (4) 番号はSQLが内部処理(絞りこみやソート)される順番とも考えています。 この場合にてインデックスを作成する場合 「TABLE1 A」に IND1(A.COL1,A.COL2,A.COL3,A.COL4,A.COL6) ON TABLE1 の複合インデックスを作成すべきか、それとも番号単位に個別に索引を作成した方が良いのか悩んでいます。 番号単位だと例えば IND1(A.COL1,A.COL2) IND2(A.COL3,A.COL4) IND3(A.COL6) アドバイスなどあればよろしくお願いします。
- ベストアンサー
- その他(データベース)
- SQL文について
テーブルの結合について教えてください。 (DBはオラクルです) select * from table1,table2 where table1.カラム名=table2.カラム名; で、結合が出来ることは分かりました。 やりたいことはテーブルの結合と、ある期間のデータを持ってきたいのです。 select カラム名 from table1 where カラム名 between '20020213' and '20020218'; で期間を決めて引き出すやり方も分かっています。 一度に結合と期間を決めて引き出すやりかたってどうすればよいですか? それとも不可能ですか? 教えてください。
- ベストアンサー
- その他(プログラミング・開発)
- ORACLEでwhere句の検索順序
Oracle9i windows2000です。 以下のようなテーブルがあります。 table_a ----------------------- id NUMBER(10,0) NOT NULL, sort NUMBER(10,0) NOT NULL, name VARCHAR(10), text VARCHAR(255) この条件で、以下のふたつのSELECT文を発行した時、パフォーマンスが良いのはどちらですか? Oracleでは後ろから検索されると聞いたことがあるのですが本当でしょうか? ※idにプライマリキー、 id,sortにインデックスが貼ってあります。 (1)SELECT text FROM table_a WHERE id = 1 AND sort = 2 AND name = 'a' (2)SELECT text FROM table_a WHERE name = 'a' AND sort = 2 AND id = 1
- ベストアンサー
- その他(データベース)
- SQLServer T-SQL テーブルのJOIN
こんにちは。 テーブル"TABLE_A"、"TABLE_B"があり、 各々のテーブルにカラム"COL"があります。 カラム"COL"にインデックスを作成しています。 テーブル"TABLE_A"、"TABLE_B"をカラム"COL"で結合 する際の演算子にLIKE文を用いています。"TABLE_B"の カラム"COL"に"%"を付加していますが、これが原因で "COL"のインデックスが効きません。どのようにすれば LIKE検索でインデックスを有効にすることができるの でしょうか? SELECT * FROM TABLE_A INNER JOIN TABLE_B ON TABLE_A.COL LIKE TABLE_B.COL+'%'
- ベストアンサー
- SQL Server
補足
key_befferは既に試しており、かなり余裕を持って作っても変わりませんでした。今回max_allowed_packetも変更しましたが、改善はみられませんでした。 更に、本来はもう一列同様に作り、複合インデックスで検索したいのですが、 select * from table1 where (col1 between 1000 and 2000) and (col2 between 1000 and 2000); こちらのほうは更に厳しく、10数件のヒットしかないにも関わらず、インデックスを使用しないときと同じくらい時間がかかってしまいます。 CPUの状況を見ると、インデックスを使わないときに比べて、全然働いていないようです。