0

私はRubyOnRails 4.0ベースのアプリを持っています。私は2つのモデルを持っています:店舗と商品。システムに約150万の製品があり、インデックスを適切に使用しないとかなり遅くなります。 1 =附属2が RubyOnRailsで内部結合テーブルを作成する

  • 製品を提携していない=

    いくつかの基本的な情報

    • ストアにhas_many製品
    • Store.affiliate_type_idが使用されているが、 "category_connection_id"(整数)と「is_availableなどの属性を持っています"(ブール値)

    In FeededProductモデル:

    scope :affiliated, -> { joins(:store).where("stores.affiliate_type_id = 1") } 
    

    このクエリを約500msで基本的にウェブサイトを中断するを取ります

    FeededProduct.where(:is_available => true).affiliated.where(:category_connection_id => @feeded_product.category_connection_id) 
    

    対応のpostgresql:

    FeededProduct Load (481.4ms) SELECT "feeded_products".* FROM "feeded_products" INNER JOIN "stores" ON "stores"."id" = "feeded_products"."store_id" WHERE "feeded_products"."is_available" = 't' AND "feeded_products"."category_connection_id" = 345 AND (stores.affiliate_type_id = 1) 
    

    更新。 PostgreSQLは、EXPLAIN:

              QUERY PLAN 
    ------------------------------------------------------------------------------------------------- 
    Hash Join (cost=477.63..49176.17 rows=21240 width=1084) 
        Hash Cond: (feeded_products.store_id = stores.id) 
        -> Bitmap Heap Scan on feeded_products (cost=377.17..48983.06 rows=38580 width=1084) 
         Recheck Cond: (category_connection_id = 5923) 
         Filter: is_available 
         -> Bitmap Index Scan on cc_w_store_index_on_fp (cost=0.00..375.25 rows=38580 width=0) 
           Index Cond: ((category_connection_id = 5923) AND (is_available = true)) 
        -> Hash (cost=98.87..98.87 rows=452 width=4) 
         -> Seq Scan on stores (cost=0.00..98.87 rows=452 width=4) 
           Filter: (affiliate_type_id = 1) 
    (10 rows) 
    

    質問:がどのように考慮に参加し、これより速く、内側を取るインデックスを作成することができますか?

  • +0

    'EXPLAIN ANALYZE'はより有用な詳細を返します。 –

    +0

    ありがとうございますが、私はRubyOnRailsでそれを行うための良い方法を見つけることができませんでした。ここにアドバイスはありますか? – Christoffer

    +0

    PostgreSQLでは、 'explain'の代わりに' explain analyze'を使います。 –

    答えて

    1

    これは、PostgreSQLが選択する結合アルゴリズムによって異なります。クエリでEXPLAINを使用して、PostgreSQLがクエリをどのように処理するかを確認してください。

    これら

    が参加したアルゴリズムに応じて答えます:

    1. ネストされたループに参加あなたは内部関係(下の表の結合条件にインデックスを作成する必要があります。ここ

      EXPLAIN出力にあります)。あなたは外側の関係、列のインデックスの場合は、さらに、すなわち(かなり選択性を向上WHEREに表示される列を追加することで、物事を改善大幅にインデックス・スキャン時に除外された行の数を減らす。
      ありそれはここではしてそれらの列に両方のテーブルにインデックスを持っているのに役立ちますこれらの条件は、テーブル内の行の大半をフィルタリング場合、クエリをスピードアップします。

    2. ハッシュが

      に参加WHERE句に表示されますWHERE句この条件では、表のほとんどの行がフィルタ処理されます。

    3. マージが

      は、ここでは、PostgreSQLはソートにインデックス・スキャンを使用できるようにするために、マージ条件の列に索引を必要とする参加。さらに、WHERE句に表示される列を追加することもできます。

    インデックスが使用される場合は、常にEXPLAINでテストしてください。そうでない場合は、使用できないか、クエリを使用するとシーケンシャルスキャンよりもクエリが遅くなる可能性があります。十分な行をフィルタリングしないためです。

    +0

    Laurenzありがとう、私は本当に説明しなかったので、私はそれについて考えなかった。私は出力を私の質問に加えましたが、正直言って、それをどう解釈するのか分からないので、私にはあまり言いません。あなたは私に手を差し伸べることができますか? – Christoffer

    +0

    実動システムから 'EXPLAIN'出力が必要です。テストシステムでは、すべてがうまくいくように見えます(内部テーブルの行は453行、外部テーブルのインデックスは使用されています)。 –

    +0

    私は生産システムのためにそれをやり直しました。 FeededProductsには約1.5Mがあり、店舗には1.200項目(アフィリエイトのフィルタあり、おそらく453)があることに注意してください。 FeededProductsの読み込みは時間がかかるものです。 – Christoffer

    関連する問題