私はしばらくの間、同じ線に沿った問題に苦労してきました-レールで効率的なクエリを実行します。私は現在、500,000 レコードのモデルに対してクエリを実行し、返された結果に関する記述的な統計を取得しようとしています。
概要として、一連の基準に一致する多数の製品を抽出したいと考えています。私はしたい...
- レコードの数を数えます (何もない場合は、特定のアクションを抑制したい)
- 一致するレコードの最大価格と最小価格を特定し、特定の範囲内にあるアイテムの数を計算します
現状では、この一連のコマンドは、私が望んでいたよりもはるかに長い時間がかかり (私のデスクトップ コンピューターでローカルに実行すると 26000 ミリ秒)、8 つまたは 9 つのアクティブなレコード アクションが含まれ、それぞれに約 3000 ミリ秒かかります。
これを処理するのが非常に遅くなるために私が間違っていることはありますか? どんな提案も素晴らしいでしょう
私のコントローラーのコードは次のとおりです。
filteredmatchingproducts = Allproduct.select("id, product_name, price")
.where('product_name LIKE ?
OR (product_name LIKE ? AND product_name NOT LIKE ? AND product_name NOT LIKE ? AND product_name NOT LIKE ? AND product_name NOT LIKE ? AND product_name NOT LIKE ?)
OR product_name LIKE ? OR product_name LIKE ? OR product_name LIKE ? OR product_name LIKE ? OR (product_name LIKE ? AND product_name NOT LIKE ?) OR product_name LIKE ?',
'%Bike Box', '%Bike Bag%', '%Pannier%', '%Shopper%', '%Shoulder%', '%Shopping%', '%Backpack%' , '%Wheel Bag%', '%Bike sack%', '%Wheel cover%', '%Wheel case%', '%Bike case%', '%Wahoo%', '%Bicycle Travel Case%')
.order('price ASC')
@selected_products = filteredmatchingproducts.paginate(:page => params[:page])
@productsfound = filteredmatchingproducts.count
@min_price = filteredmatchingproducts.first
@max_price = filteredmatchingproducts.last
@price_range = @max_price.price - @min_price.price
@max_pricerange1 = @min_price.price + @price_range/4
@max_pricerange2 = @min_price.price + @price_range/2
@max_pricerange3 = @min_price.price + 3*@price_range/4
@max_pricerange4 = @max_price.price
if @min_price == nil
#don't do anything - just avoid error
else
@restricted_products_pricerange1 = filteredmatchingproducts.select("price").where('price BETWEEN ? and ?', 0 , @max_pricerange1).count
@restricted_products_pricerange2 = filteredmatchingproducts.select("price").where('price BETWEEN ? and ?', @max_pricerange1 + 0.01 , @max_pricerange2).count
@restricted_products_pricerange3 = filteredmatchingproducts.select("price").where('price BETWEEN ? and ?', @max_pricerange2 + 0.01 , @max_pricerange3).count
@restricted_products_pricerange4 = filteredmatchingproducts.select("price").where('price BETWEEN ? and ?', @max_pricerange3 + 0.01 , @max_pricerange4).count
end
編集 明確にするために、私が持っている基本的な質問は、なぜこれらのクエリのそれぞれを大規模な Allproduct データベースで実行する必要があるのか 、前者の結果に対して後者のクエリを実行する方法がないのですか (つまり、filteredmatchingproducts 自体を使用しないクエリごとに再計算します)? 他のプログラミング言語では、操作を実行する前に変数を再度計算するのではなく、変数を記憶し、それらの記憶された値の操作を実行できることに慣れています - これはRailsの考え方ではありませんか?