试图优化PostgreSQL嵌套的WHERE IN

时间:2016-02-29 13:02:51

标签: sql postgresql postgresql-performance

我有一个Postgres(9.1)客户数据库,类似于:

customers.id
customers.lastname
customers.firstname

invoices.id
invoices.customerid
invoices.total

invoicelines.id
invoicelines.invoiceid
invoicelines.itemcode
invoicelines.price

我建立了一个搜索,其中列出了购买某个商品的所有客户(例如' abc')。

Select * from customers WHERE customers.id IN
    (Select invoices.customerid FROM invoices WHERE invoices.id IN
        (Select invoicelines.invoiceid FROM invoicelines WHERE
        invoicelines.itemcode = 'abc')
    )

搜索工作正常并提出正确的客户,但大约需要10秒左右的数据库,包含200万张发票和200万个订单项。

我想知道是否有其他方法可以减少一点。

3 个答案:

答案 0 :(得分:3)

另一种方法是使用EXISTS

Select * 
from customers 
WHERE EXISTS (
   Select invoices.customerid 
   FROM invoices 
   JOIN invoicelines
      ON invoicelines.invoiceid = invoices.id AND
         invoicelines.itemcode = 'abc' AND
         customers.id = invoices.customerid)

答案 1 :(得分:1)

您可以改用exists。我怀疑这可能效果很好:

Select c.*
from customers c 
where exists (Select 1
              from invoices i join
                   invoicelines il
                   on i.id = il.invoiceid and il.itemcode = 'abc'
              where c.id = i.customerid
             );

为此,您需要确保拥有正确的索引:invoices(customerid, id)invoicelines(invoiceid, itemcode)

答案 2 :(得分:0)

您是否希望customer中该客户商品的itemcode所有行和列均为'abc'?如果您加入customerid,则可以找到这些项目的所有客户信息。如果您在该列表中有重复项,则可以使用DISTINCT,每customerID只会为您提供一个条目。

SELECT 
    DISTINCT [List of customer columns] 
FROM 
    customers 
INNER JOIN 
    invoicelines 
ON 
    customers.customerid = invoicelines.customerid
AND
    invoicelines.itemcode = 'abc'