5

大きなテーブルからフェッチするクエリを最適化するためのヒントが必要です。

この例では、5 つのテーブルがあります。

Brands
- id_brand
- b_name

Products
- id_product
- p_name
- ean
...
- fk_brand

Prod_attributes
- id_prod_att
- size_basic
...
- fk_product

Stores
- id_store
- s_name
...

Stocks
- id_stock
- stock_amount
- fk_prod_att
- fk_store

限られた株式の順序付きリストを使用したクエリが必要なので、これが私が使用した一般的なアプローチです。

SELECT stores.s_name, stocks.stock_amount, prod_attributes.size_basic, 
products.p_name, products.ean, brands.b_name 

FROM (stocks 
    INNER JOIN stores 
    ON stocks.fk_store = stores.id_store) 
    INNER JOIN (prod_attributes 
        INNER JOIN (products 
            INNER JOIN brands 
            ON products.fk_brand = brands.id_brand) 
        ON prod_attributes.fk_product = products.id_product) 
    ON stocks.fk_prod_att = prod_attributes.id_prod_att 

ORDER BY s_name, p_name, size_basic 

LIMIT 25 OFFSET 0

これは小さなテーブルでは高速に機能しますが、テーブルが大きくなると、クエリのコストが非常に高くなります。Stocks に 350 万行、Prod_attributes に 300K、25K Products の場合、8800 ミリ秒以上で実行されますが、これは私には受け入れられません。

すべての forgein キーにはインデックスがあり、DB は最近バキューム分析されました。

問題が ORDER BY 部分にあることはわかっています。これは、クエリがインデックスを使用せず、シーケンシャル スキャンを実行するためです。順序付けを削除すると、クエリは非常に高速になります。

これを解決するために、ORDER BYを削除できることはわかっていますが、それは私にとって実行可能なオプションではありません。DBまたはマテリアライズドビューの非正規化もここで役立つ可能性があります-可能であればこれを避けたいと思います。

このクエリを高速化するために他に何ができますか?

EXPLAIN ANALYZE:
- 順序を指定すると遅い: http://explain.depesz.com/s/AHO
- 順序を指定しないと速い: http://explain.depesz.com/s/NRxr

4

1 に答える 1

1

stores可能な方法は、結合から削除することです。代わりに、次のことができます。

  • storesストアド プロシージャまたはソース コード内で( order by ) をループしs_name、ストアごとに で結合フィルタリングを実行しstocks.fk_storeます。十分な数のレコードを取得するたびに、ループを中断できます。

  • 可能であれば、結合内のタプルの数を大幅に減らすために、キーstocksを使用して分割します。fk_store

このようにして、あなたは良い利益を得るはずです。

于 2012-11-07T14:24:10.043 に答える