我需要一些技巧来优化从大表中获取的查询。
在这个例子中,我有 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 中有 3,5M 行,Prod_attributes 中有 300K 行,25K 产品在超过 8800 毫秒内执行,这对我来说是不可接受的。
所有伪造的密钥都有索引,最近对 DB 进行了真空分析。
我知道问题在于 ORDER BY 部分,因此查询不使用索引并进行顺序扫描。如果我删除排序,那么查询会非常快。
为了解决这个问题,我知道我可以删除 ORDER BY,但这对我来说不是可行的选择。数据库或物化视图的非规范化在这里也可能有所帮助 - 如果可能的话,我想再次避免这种情况。
我还能做些什么来加快这个查询?
解释分析:
- 订购缓慢: http: //explain.depesz.com/s/AHO
- 快速无订购:http ://explain.depesz.com/s/NRxr