一度の処理で参照するデータベースのテーブル数が増えると速度が低下するのでしょうか?


RailsでWebアプリを作っています。最大で1990年~2010年まで20年間 * 4四半期/1年 = 80 個のテーブルを作るとします。
一回の処理でそれぞれ20個、40個、80個のテーブルからデータを参照して表示する場合、
一度に参照するテーブルの数が増えるに従ってどれくらい速度が低下するものなのでしょうか。
また、一度に参照するテーブルの数は何個以内に抑えるのが望ましいのでしょうか。

データベースを扱うのは初めてで設計の目安など分からないので、どなたか教えて頂けないでしょうか。よろしくお願いします。

回答の条件
  • 1人5回まで
  • 登録:
  • 終了:2009/10/31 06:51:46
※ 有料アンケート・ポイント付き質問機能は2023年2月28日に終了しました。

ベストアンサー

id:cuspos No.1

回答回数49ベストアンサー獲得回数10

ポイント100pt

こんばんは。


まずテーブル設計がRailsの流儀と異なりますので、アプリを作った際に苦労すると思われます。Railsではmodel:table=1:1です。これが基本です。


今のテーブル設計だとするとテーブルを発行するSQLが運用中に発生する事になります(データを追加しないなら話は別です)。で、それに対応するモデルをそのたびに作るか、当初よりモデルを通常のモデルとは異なる形で工夫するか・・・等々難易度が高くなりそうな気がします。なによりRailsの強みが消えてしまう可能性が高そうです。

※既存のテーブル設計がそうなっているとか、データ量が膨大なためSQLの実行速度が出ないため等の理由がある場合は別です。


新規で作る物であると仮定すると私なら以下のような形で設計します。

「1990年〜2010年まで20年間 * 4四半期/1年 = 80 個のテーブル」

ではなく上記の物を一つのモデル、テーブルで作る。

で、モデルのnamed_scope等を使って期間を区切る等で対応します。

データ数が膨大で速度が出ない場合はテーブル分割する、もしくはRDBを捨ててkey:value型のデータストアを使う等考えます。


単純に「一度の処理で参照するデータベースのテーブル数が増えると速度が低下するのでしょうか?」という質問内容に関して言うと、「速度低下します」という答えになります。ただそれが無視できる範囲の物なのか?トータルで見て遅いのか?負荷がかかったときに遅くなるのか?データ量により重くなる等ケース・バイ・ケースですので、そこは個別に対応していくしかないというのが正直なところです。※キャッシュを使うという手もあります。

id:tyn

cusposさん、いつも回答有難うございます。モデルやテーブルを大量生成するのは現実的ではないのですね。

今回作っているのは上場企業の財務諸表を登録するデータベースでして、上場企業数 4000弱 * 4四半期 * 10~30年 = 16万~48万 件ほどのレコードが

理論上1つのテーブルに収まる可能性があります。カラムの数は最高で100くらいだと思うのですが、この場合データ量は何件ほどから速度が低下するのでしょうか?

まだ実運用でどれくらい負荷がかかるか等全く分からず回答しにくいとは思うのですが、もしよければ教えて頂けないでしょうか。よろしくお願いします。

2009/10/24 19:04:39

その他の回答3件)

id:cuspos No.1

回答回数49ベストアンサー獲得回数10ここでベストアンサー

ポイント100pt

こんばんは。


まずテーブル設計がRailsの流儀と異なりますので、アプリを作った際に苦労すると思われます。Railsではmodel:table=1:1です。これが基本です。


今のテーブル設計だとするとテーブルを発行するSQLが運用中に発生する事になります(データを追加しないなら話は別です)。で、それに対応するモデルをそのたびに作るか、当初よりモデルを通常のモデルとは異なる形で工夫するか・・・等々難易度が高くなりそうな気がします。なによりRailsの強みが消えてしまう可能性が高そうです。

※既存のテーブル設計がそうなっているとか、データ量が膨大なためSQLの実行速度が出ないため等の理由がある場合は別です。


新規で作る物であると仮定すると私なら以下のような形で設計します。

「1990年〜2010年まで20年間 * 4四半期/1年 = 80 個のテーブル」

ではなく上記の物を一つのモデル、テーブルで作る。

で、モデルのnamed_scope等を使って期間を区切る等で対応します。

データ数が膨大で速度が出ない場合はテーブル分割する、もしくはRDBを捨ててkey:value型のデータストアを使う等考えます。


単純に「一度の処理で参照するデータベースのテーブル数が増えると速度が低下するのでしょうか?」という質問内容に関して言うと、「速度低下します」という答えになります。ただそれが無視できる範囲の物なのか?トータルで見て遅いのか?負荷がかかったときに遅くなるのか?データ量により重くなる等ケース・バイ・ケースですので、そこは個別に対応していくしかないというのが正直なところです。※キャッシュを使うという手もあります。

id:tyn

cusposさん、いつも回答有難うございます。モデルやテーブルを大量生成するのは現実的ではないのですね。

今回作っているのは上場企業の財務諸表を登録するデータベースでして、上場企業数 4000弱 * 4四半期 * 10~30年 = 16万~48万 件ほどのレコードが

理論上1つのテーブルに収まる可能性があります。カラムの数は最高で100くらいだと思うのですが、この場合データ量は何件ほどから速度が低下するのでしょうか?

まだ実運用でどれくらい負荷がかかるか等全く分からず回答しにくいとは思うのですが、もしよければ教えて頂けないでしょうか。よろしくお願いします。

2009/10/24 19:04:39
id:kn1967 No.2

回答回数2915ベストアンサー獲得回数301

ポイント100pt

落ちる可能性が高いですが、体感できるほどかどうかはデータ量や、

どのように集計したいのかが判らないので何とも・・・。


速度は気になる所ですが、取り扱い安さから考えると、

時系列データは縦一列に並べる感じで1つにしてしまうほうが楽です。

(SQL書いてみれば判りますが一度に10テーブルでも気が滅入りますよ。)


レコード数の多さが気になっておられるのかもしれませんが、

データベースに取ってみれば10万でも100万でも問題になりません。

(ただし、インデックスを設定しておかなければなりません。

カラムの内容も、どのような集計を行う予定なのかも判らないので、

どのカラムにどのようにインデックスをつけるべきかは・・・。)


データ比較等もお考えだと思いますが、SQL1つで1つのテーブルを使い、

複数の集計を同時にこなす事も可能ですし、

1990年と2000年、2008年の同四半期のデータを横並びに出力するなども可能です。

(SQLで集計だけ行ってRuby側で整形して出力という手でももちろんOK。)

id:tyn

kn1967さん、本日は回答有難うございます。レコード数は100万でもいけてしまうのですね。

上場企業の四半期の財務諸表の各項目のデータが収まる予定ですので、証券コードと決算年度に(決算年度に沿って時系列的に登録されるとは限らないですが)

インデックスを設定するのが良いでしょうか?インデックスについてはこれから調べないといけませんが…。

ご指摘の通り、データ比較等も行いたいと考えています。SQLもほぼ書いたことがないので、こちらも勉強が必要ですね。

2009/10/24 19:20:19
id:cuspos No.3

回答回数49ベストアンサー獲得回数10

ポイント100pt

こんばんは。

速度はデータ量だけによりません。indexの張り方、SQLの作り方、入っているデータの形により何とも言えないというのが正直なところです。このあたりのノウハウはRailsというより、DB依存の内容です。

ただ既にデータが手元にありそうな雰囲気ですので、これをインポートして、ベンチマークを取ってみるといいと思います。

とりあえずはデータつっこんでみて、SQLのみ発行してどれくらいで返ってくるか確認(http://www.daito.ac.jp/~ikeuchi/webdb/mysql_5.htmlなんか参考になるでしょうか)、最終的にはab等で負荷テストをかけてみるのがいいかと思います。

※CRUD系の動作を想定していたので、前述のような回答になりましたが、create、editの動作は少なそうですね。・・・だとすると、SQLが速度面のボトルネックになるようだったら、テーブル分けちゃうのも悪くない手かもしれません。あとデータの性質から言うとトランザクションもいらないのかな?DBがMySQLだとするとMyIsamで作って適切にindex張ってあげれば、SQLのスピードは問題無さそうな気もします。

id:tyn

回答有難うございます。手元にデータはなくて、必要な時にデータベースに登録する感じです。

レコード件数が増えてきたらまた負荷対策も考えてみようと思います。

2009/10/27 23:56:01
id:sirotugu40 No.4

回答回数449ベストアンサー獲得回数14

ポイント22pt

>RailsでWebアプリを作っています

>一回の処理でそれぞれ20個、40個、80個のテーブルからデータを参照して表示する場合、

表示形式(View)に対応した中間テーブルを作って、一度そちらにデータを入れて

それを読み込むようにしたほうが無難。

Railsは実際のところ遅いですからね。

id:tyn

sirotugu40さん、コメント有難うございます。

中間テーブルというのは今日初めて聞きました。調べてみようと思います。

2009/10/27 23:56:55
  • id:kn1967
    (前置き)
    インデックスは複数のカラムの組み合わせで指定できます。
    MySQLのインデックスは基本的に昇順で並びます。
    インデックスは1つのテーブルに対して複数作るすることが出来ます。
    どのインデックスを使うかはMySQLのオプティマイザと呼ばれる部分が決めます。
    インデックスの作成・削除・再構築を行ってもテーブルには影響を与えません。

    (インデックスの張り方の例)
    仮に「証券コード, 年, 四半期, 決算年度、・・・」という項目があるとします。
    (a)1つの企業を対象にデータを見る場合用
      証券コード+年+四半期
      これはインデックスキーではなくをプライマリーキーとして登録するほうが、
      良いでしょう。
    (b)決算年度単位で集計などを行う場合用
      決算年度+証券コード
    など・・・
    適切なインデックスが存在していない場合、毎回毎回全レコードを総舐するので、
    処理は劇的に遅くなります。

    総舐とは広辞苑を毎回先頭ページから順に探していくようなものです。
    インデックスは文字通り「目次」を利用して、
    「はてな」なら「は」で絞込み、次に「て」で、というように効率良く処理します。
    ・・・広辞苑に「はてな」が存在するかどうかは調べてません(笑)

    以上、とりあえず。
    (Railsでユーザーインターフェースを作る作業を1とすると、
    データベースのほうは3でも足りないかもしれない・・・。)
  • id:cuspos
    横道にそれますが…
    個人的には今の段階では、とりあえず動くレベルで作っちゃうのが早いかもと思います。
    ※このあたりは意見が分かれるところです。客先に出すものだとそうは行かないだろうしとか。

    DBに関してはSQLの組み方index次第でかなり差がでます。
    こればかりは実データがないと何とも言えません。マシンスペックにもよりますし。

    Railsが実効速度で遅い&マシンスペックをくうのも確かです(rubyが動的型付けなんで言語仕様とも…)。
    ただトータルで見たとき許容できないほど遅いのか?というとWEBアプリを作るという面では何とかなるレベルでもあります。
    以下のURLは参考になります。
    http://www.rmake-labo.com/akasata/articles/show/168
  • id:tyn
    コメント有難うございます。indexについてなのですが、証券コードで銘柄を指定して決算年度で範囲を指定して絞り込んで、決算年度でソートするといった場合だと複合インデックスを張った方が速くなるのでしょうか?
  • id:kn1967
    >証券コードで銘柄を指定して決算年度で範囲を指定して絞り込んで

    その順番であれば「証券コード+決算年度」の順番になります。
    インデックスが使われれば、ソートは既に行われているのと同じようなものなので、
    絞込みもソートいずれも高速化が期待できます。


    MySQLの view は今のところ「複雑なSQLを記憶させておくだけのもの」なので、
    SQLはRails側に記述する今回のシステムでは必要無いですし、
    Railsが遅いというのも、複雑なシステムを組む場合に考慮しなければならないというだけで、
    今回のようなシステムの場合は工期が短くなるという利点のほうが大きいです。
    (必要か不必要か、関係するか無関係かにかかわらず、知っている単語を、
    ただ書きたいだけの困ったチャンなので、流されないように気をつけてください。)
  • id:tyn
    kn1967さん、コメント有難うございます。

    インデックスについては調べて、必要であればまた質問を立てようと思います。
    MySQLのviewは使う必要がないと理解しました。

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

回答リクエストを送信したユーザーはいません