2016-02-29 59 views
1

我有一个Postgres(9.1)客户类似数据库:试图优化PostgreSQL的嵌套其中

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秒左右2张万元的发票和200万个项目的数据库上。

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

+0

您是否尝试过连接? '从客户的内部联合发票*中选择* customeromerid = customers.id内部联接inoicelines.invoiceid = invoices.invoiceid其中invoicelines.itemcode ='abc'' – artm

+0

阅读:http://stackoverflow.com/tags/postgresql-performance/info然后[**编辑您的问题**](http://stackoverflow.com/posts/35700292/edit)并添加缺少的信息 –

回答

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

您可以切换到使用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)

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'