PostgreSQL简单查询优化

PostgreSQL简单查询优化,sql,postgresql,query-optimization,Sql,Postgresql,Query Optimization,PostgreSQL 8.4;三张表-门店~100k,主键id,fk供应商id和物料id,供应商~10PK供应商id,物料~1000PK物料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 A

PostgreSQL 8.4;三张表-门店~100k,主键id,fk供应商id和物料id,供应商~10PK供应商id,物料~1000PK物料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扫描,这让我想到我需要安排它,以便扫描/筛选只应用于存储表的一个子集-但是iirc在任何情况下都需要扫描表,所以可能使用Seq扫描以外的其他方法?索引扫描不会有帮助,因为我不会按索引进行筛选。。。我在这里感到困惑,因为这似乎更多的是PostgreSQL优化器做出的选择,而不是我可以随意改变的东西


如果你想知道,这是一项作业的一部分,我在这里问这个问题是因为我花了好几个小时研究这个问题,没有找到任何相关的东西,我只是放弃了,但我仍然很好奇…

你可能可以用索引来解决这个问题。因为自然连接,所以有点难分辨键是什么。我建议使用而不是自然连接,这样您至少可以看到正在使用哪些键,并且如果其中一个表被修改,它不会破坏连接


我认为在itemitem\u name、item\u id上建立索引将有助于查询计划。

将很难优化,因为它看起来不错,请尝试以下方法以避免子查询:

SELECT 
    store.quantity, 
    store.price, 
    supplier.supplier_name 
FROM store 
    INNER JOIN item
        ON store.item_id = item.item_id
    INNER JOIN supplier
        ON supplier.supplier_id = store.supplier_id
        AND supplier.item_name = 'SomeName'
WHERE 
    store.price > 500 
    AND store.quantity BETWEEN 0 AND 100;
在两者之间使用更好

另外,在以下位置添加索引:

store.item\u id item.item\u id 供应商项目名称
这样做只会将该项的哈希值从20.75提高到8.27,这与6000ish seq扫描相比无关紧要。我添加了连接到OPI的相关索引,在发布问题时没有考虑全局变化,但是您的建议肯定是有效的——添加的正确索引是StureItMyID,价格,这导致了一个非常不同的查询计划,并将成本降低到原来的5%:-我不把您的答案标记为接受,尽管如此,因为我仍然对是否可以在本地进行优化感兴趣-op说无论如何@user742925。您可以提示查询对连接使用基于哈希的算法,而不是嵌套循环。我的猜测是,这可能是性能瓶颈所在。