更快的CROSS JOIN替代方案 - PostgreSQL

时间:2010-01-14 19:49:46

标签: postgresql cross-join

我正在尝试交叉加入两个表,客户和项目,因此我可以按项目报告按客户创建销售。我有2000个客户和2000个项目。

SELECT customer_name FROM customers; --Takes 100ms

SELECT item_number FROM items; --Takes 50ms

SELECT customer_name, item_number FROM customers CROSS JOIN items; Takes 200000ms

我知道这是400万行,但有可能让它运行得更快吗?我想最终加入这样的销售表:

SELECT customer_name, item_number, sales_total FROM customers CROSS JOIN items LEFT JOIN sales ON (customer.customer_name = sales.customer_name, item.item_number=sales.item_number);

销售表显然不会包含所有客户或所有商品,因此此处的目标是生成一份报告,其中显示所有客户和所有商品以及已售出和未售出的商品。

我正在使用PostgreSQL 8.4

5 个答案:

答案 0 :(得分:4)

回答你的问题:不,你不能比那更快地进行交叉连接 - 如果可以的话那就是CROSS JOIN的实现方式。

但实际上你不想要交叉加入。您可能需要两个单独的查询,一个列出所有客户,另一个列出所有项目以及是否已售出。

答案 1 :(得分:1)

这确实需要多个报告。我可以想到几个可以产生更有效的信息包装的几个方面:

  1. 报告:按客户/项目进行的所有购买计数(显而易见)。
  2. 报告:客户未购买的所有商品的清单。
  3. 报告:报告#2(项目数量)摘要,以便优先考虑哪些客户关注。
  4. 报告:所有未按项目购买的客户的清单。
  5. 报告:报告#3摘要(客户数量),以确定最受欢迎和不受欢迎的项目,以便采取进一步行动。
  6. 报告:过去购买商品但未在其报告期内购买商品的所有客户的列表。该报告仅在销售表具有日期并且预期客户是常规买方(即一次性小部件)时才相关。对于服务合同这样的事情也行不通。
  7. 这里的要点是,不应该坚持该工具立即处理每个可能的结果并生成更多数据,任何人都可以手动消化。人们应该让数据的最终用户和消费者了解他们的需求,并根据这些需求定制输出。从长远来看,这将使双方的生活更加轻松。

答案 2 :(得分:0)

我无法想象会有第三方解决方案,PostgreSQL程序员最了解他们的系统,并会对其进行大量优化。

答案 3 :(得分:0)

如果您希望查看给定客户的所有项目(即使客户没有项目),我宁愿尝试

SELECT c.customer_name, i.item_number, s.sales_total
FROM customers c LEFT JOIN 
    sales s ON c.customer_name = s.customer_name LEFT OIN
    items i on i.item_number=s.item_number

这应该为您提供所有客户的列表,以及按销售加入的所有项目。

答案 4 :(得分:0)

也许你想要这样的东西?

select c.customer_name, i.item_number, count( s.customer_name ) as total_sales
from customers c full join sales s on s.customer_name = c.customer_name
full join items i on i.item_number = s.item_number
group by c.customer_name, i.item_number