- 締切済み
飛び飛びデータ検索
MYSQLにて、データ検索を行っております。 A番目のレコードからB個飛ばしで360個のデータを抽出したいのですが、 なかなか速くて良い方法が見つかりません。 例えば、5番目,8番目,11番目・・・と言う風に 最初とインターバルが決まっています。 今、試してみたものが、FOR文で"何番目のレコード"という値を360個取得し、 INを使って検索しています。 しかし、この方法だと、平均1SEC,最悪インターバルの代わった後だと3SEC 掛かってしまいます。 目標は、0.1SEC。とにかく速ければ速いほど良いと言うことなのですが・・・ 何か良い方法・ヒントなどありましたら、ご教授下さい。 宜しくお願いいたします。
- みんなの回答 (2)
- 専門家の回答
みんなの回答
- aton
- ベストアンサー率47% (160/334)
MySQLには詳しくないので以下DBMS一般の話になりますが,たぶん,無理です。 ハードディスクのシークは,民生用だと現在最も高速なものでもサブ10ミリ秒がやっとだと思います。仮にシーク速度を10ミリ秒とすると,360個のデータにアクセスするにはシークだけで0.36秒かかります。読み出しその他の処理を加えて1~3秒というのは妥当な値だと思います。 これ以上の高速化を目指すなら,考えられるのは, ・ディスクアクセスを減らす →キャッシュサイズを大きくとる ・シークを減らす →データを(インターバル間隔で)連続配置する →データ番号をインターバルで割った余りを格納するカラムを追加し,そこにインデックスを張る (この方法が有効に機能するのは,インターバルが変化しないときのみ。インターバルを複数用いる場合も,ある程度の高速化は期待できるでしょうが,シークは削減できないので効果は限定的になるでしょう。またカラムが増えるのでストレージコストは増加しますし,更新コストも大きくなります) くらいでしょう。 あるいは(この処理の目的がわからないので適当な答ではないかもしれませんが)データの更新があまり頻繁でなく,参照速度が重要なのであれば,私なら,予め答を計算したものを格納しておいて,それにアクセスするという方式を取ります。更新があった場合は再計算が必要なので更新コストは極めて高くなりますが,参照速度は速くなります。
- snoopy64
- ベストアンサー率42% (337/793)
初期値=f、間隔=i、個数=c、レコード番号=r とおくと、 mod(r-f,i)=0・・・(レコード番号-初期値)が間隔で割り切れる かつ (r-f)/i<c ・・・(レコード番号-初期値)/間隔が個数未満 かつ r≧f ・・・レコード番号≧初期値 という条件でどうでしょう。 SQLはよく知らないので、レコード番号なんてものが使えるのかはわかりませんが。
お礼
早速のご回答有り難うございます。 似たような形のものを試してみましたが、 レコード1つ1つに対して計算を行うようで、 少し時間が掛かってしまいます。 全レコード数は2万件です。 実際は20万件程度になると考えております。 計算をせずにまとめて一気に取れる方法など ありませんでしょうか?