【发布时间】:2014-07-06 12:47:26
【问题描述】:
PostgreSQL 8.4;三张表 - store (~100k, pk id, fk supplier_id & item_id), supplier(~10 pk supplier_id), item(~1000 pk item_id);
我创建了以下查询来获取我需要的数据:
SELECT store.quantity, store.price, x.supplier_name
FROM store NATURAL JOIN
(SELECT * FROM item NATURAL JOIN supplier) AS x
WHERE store.price > 500 AND store.quantity > 0 AND
store.quantity < 100 AND
x.item_name = 'SomeName';
查询计划:
Nested Loop (cost=20.76..6513.55 rows=8 width=229)
-> Hash Join (cost=20.76..6511.30 rows=8 width=15)
Hash Cond: (store.item_id = item.item_id)
-> Seq Scan on store (cost=0.00..6459.00 rows=8388 width=23)
Filter: ((price > 500::numeric) AND (quantity > 0) AND (quantity < 100))
-> Hash (cost=20.75..20.75 rows=1 width=8)
-> Seq Scan on item (cost=0.00..20.75 rows=1 width=8)
Filter: ((item_name)::text = 'SomeName'::text)
-> Index Scan using supplier_pkey on supplier (cost=0.00..0.27 rows=1 width=222)
Index Cond: (supplier.supplier_id = store.supplier_id)
现在的目标是通过优化查询本身将成本降低 30% 以上。我发现的这个问题的唯一实例是通过修改表或服务器设置来解决的,但我希望通过修改查询来解决这个问题,这就是我研究不足的地方。
显然要解决的问题是 Seq Scan,这让我想到我需要安排它,以便扫描/过滤仅应用于存储表的子集 - 但 iirc 你需要扫描表任何这种情况,所以也许使用 Seq Scan 以外的东西?索引扫描无济于事,因为我不会按索引进行过滤...我在这里感到困惑,因为这似乎更像是 PostgreSQL 优化器做出的选择,而不是我可以随意更改的东西...
(如果您想知道,这是作业的一部分,我在这里问是因为我花了好几个小时研究这个问题,但没有找到任何相关的东西,我就放弃了,但我'我还是很好奇...)
【问题讨论】:
标签: sql postgresql query-optimization