1

モデル製品があり、それはカテゴリ (製品テーブルのcategory_id) に属しています。最初の 20 個の製品とそのカテゴリ名を取得するクエリを作成したいと考えています。私はそれを取得する2つの方法があります:

  1. includes次のように使用します。

    Product.includes(:category).
            order(:updated_at).
            limit(20)
    

    次のようなビューでカテゴリ名を取得します。

    <%= product.category.name if product.category %>
    

    これにより、次のようなクエリが作成されます。

    SELECT `products`.* from `products` ORDER BY `products`.updated_at LIMIT 20
    SELECT `categories`.* from `categories` WHERE `categories`.id IN (1,2,3,4,5..,25)
    
  2. joins次のように使用します。

    Product.joins("LEFT JOIN categories ON categories.id = products.category_id").
            select("products.*, categories.name as category_name").
            order(:updated_at).
            limit(20)
    

    次のようなビューで使用します。

    <%= product.category_name %>
    

    これにより、次のようなクエリが生成されます。

    SELECT products.*, categories.name as category_name from `products` LEFT JOIN categories ON categories.id = products.category_id ORDER BY `products`.updated_at LIMIT 20
    

方法 1 には、Category モデルで記述されたモデル レベルのメソッドを使用できるという利点があり、コードはより保守しやすくなります。ただし、IN 句を使用するカテゴリを見つけるために別のクエリを使用するという欠点があります。

好ましい方法はどれですか?

4

3 に答える 3

2

それは単なる好みではなく、パフォーマンスと保守性の問題です。最初に、クエリのより保守しやすいルートに進みます。特定のクエリでパフォーマンスが低下し始めた場合は、結合構文を使用するか、単純な古い sql を最初から作成して最適化します。時期尚早に最適化しないでください。実際に必要なところを最適化します。

于 2012-04-08T04:17:31.987 に答える
0

望ましい方法は、あなたが個人的に好む方法です。

includes正直なところ、anを使用することがそれほど大きな問題であるとは思いません。特に、ページに配置する内容が変更されるアプリの開発では。

私の意見では、includesほとんどの場合、そのような状況で使用してください。多くの行を格納しているtext場合や、本番環境に移行してそのクエリがボトルネックになってしまう場合を除いて、時間をかけて最適化する必要があります。

于 2012-04-08T01:47:01.040 に答える
0

あなたの例では、オプション1を使用する場合があります。これは、オプション1の方が読みやすく、それほど多くのオブジェクトをロードしていないため、パフォーマンスへの影響がそれほど深刻になることはないと思います。

より多くのデータをロードする可能性がある場合(たとえば、limit(20)パーツを削除した場合)、オプション2を使用します。これにより、必要なのが名前だけの場合に、Categoryオブジェクトをインスタンス化する必要がなくなります。小さいリストでは、このオーバーヘッドは無視できるかもしれませんが、リストが長くなるにつれて、それは重要になる可能性があります。

于 2012-04-07T19:23:31.710 に答える