2011-01-27 5 views
0

私はクライアントのサイトで作業しており、売上データをどのようにプルダウンするのかをより効率的にしようとしています。私の元々の解決策は、カスタムSQLクエリのスパゲッティが混乱して、なぜあまりにもハッキングされているのではないかと感じました。次に、関連するすべてのセールスレコードをプルダウンしてRubyで処理しようとするラッパークラス(SalesCalculator)を作成しようとしましたが、30,000件以上のレコードについては、パフォーマンスが大幅に低下し、キャッシュさえも潜在的に迷惑な(我々は> 10ページの読み込みを話している)。データの重いサイトの効率を上げるためのアイデア

私も、ちょうど私が私の全体的な目標は、私は一貫性のあるインターフェースを保つことができるように、データと私の相互作用を簡素化することであると思いEAC

のクエリを構築しようとしました。上記と同じ3年間の各年の売上高の

  • 総収入
  • が、5かそこらの部門
  • に分かれて:ここで私は一般的に、任意のページに行ってしまう物事のカップルは、 (現在および以前の年のための)部署/従業員の月別
  • 総収入
  • など

だから私の質問は、あなたたちは、大規模なデータセットと同様のことを行うのでなければならないのどんな提案/例でしょうか?

+0

30kレコードでは、私が知っているDBMS(またはRubyの場合)のパフォーマンスが低下することはありません。私はあなたに何をしているのか、データベースレイアウトの概要と最も遅いクエリのいくつかの例を教えてもらうことをお勧めします。そこで本当に間違っていることが分かります。 – fresskoma

+0

ええ、問題ありません!基本的に、売上請求書レコードには、日付、金額、トン数、従業員ID、顧客ID、製品IDが含まれます。 クエリのようなインターフェイスを構築して、必要なすべてのレコードを取得し、さまざまなサブセット、つまり特定の部門のデータセットの各年の合計売上を減らすことができました。私はこれらのことをSQLで行うことができますが、ロジックをルビに移行してより多くの制御と柔軟性を持たせることが考えられましたが、問題は30,000以上のARオブジェクトの配列が少なくとも15回反復されること(3年ごとに一度、部署ごとに)。 –

+0

ここに、あなたにアイデアを与えるためのページのスクリーンショットがあります。私は実際の販売数を削除しましたが、基本的に箱に記入しました。 http://s3.noahhendrix.com/system/1296111185_Screen%20shot%202011-01-27%20at%2012.51.48%20AM.png –

答えて

3

30kは何もありません。 SQLiteデータベースの場合でも。

あなたの問題はこれです:30,000以上のARオブジェクトが少なくとも15回反復されています - しないでください。それは悪いアイデアと悪いデザインであり、あらゆる観点から悪いことです。

あなたは既にテーブルに日付フィールドを持っていますが、なぜWHERE YEAR(date)= 2011を使用しないのですか?部門の列をデータベースに追加することができます。特定のフィールドに索引を追加して、照会のパフォーマンスを向上させることができます。検索の範囲を狭くし、実際に必要なARオブジェクトだけを持つためには、たくさんのことを行うことができます。

データベース全体を30KBのARオブジェクトにダウンロードすることは、最後にやりたいことですが、そのような解決策が必要な問題は何か想像できません。

3

あなたのデータベースをファイルシステムとして使い、Ruby via Railsを使ってレポートを構築するのはうんざりです。私はSQLを使うことに戻ります。

クエリをテストし、インデックスを追加すると、が適切に表示され、ページの読み込み時間を適切に延ばすことができます。

+0

私は同意します。 SQLがあなたのために物事を合計してみましょう。また、データベーススキーマによっては、データセットの選択に問題があるかもしれません。ほとんどの時間を取っていることを知っていますか?SQLかルビ? – murrekatt

0

データベースに計算させる必要があります。ルビーの合計を計算するよりも何倍も高速です。必要な栄養指数があることを確認してください。レールでネイティブクエリを実行

class Sales 

    # Other code 

    def self.totals (group_by, where, ...) 
    # Build the query depending of the parameters 
    sql = "SELECT SUM(amount) FROM sales ... " 
    # Execute the query 
    result = connection.execute(sql) 
    # when using mysql result will be a Mysql::Result object 
    # Finally you can wrap the totals in a nice hash 
    data = {} 
    result.each_hash do |row| 
     data[row['col']] = row['other_col'] 
    end 
    data 
    end 

これはSales.totals(..)を呼び出すことで問い合わせることができます。

あなたが他のクラスから照会したい場合は、単にSales.connection.execute(sql)

MySQLのAPIを使用します。http://www.tmtm.org/en/mysql/ruby/

0

named_scope年代の組み合わせは、移動するための方法であるかもしれないあなたはどのように記述するパラメータでそれらを養うことができますデータをフィルタリングしたい(データベースに重い作業をさせる)。

これが可能でない場合は、常にfind_each(:batch => 1000)があり、一度に1000レコードを取得します。

関連する問題