【问题标题】:SQL: How to join tables with 1+ millions of recordsSQL:如何连接具有 1+ 百万条记录的表
【发布时间】:2021-05-29 15:58:38
【问题描述】:

我想使用以下查询连接两个表(“产品”表有 150 万条记录),但 15 分钟后查询仍在运行,我的电脑过热(它是 8GB RAM 的联想 v330-14ikb ),所以我停止了它。

我对索引很陌生,我尝试创建以下内容:

  • 在订单上创建索引 customer_id_idx1 (customer_id)
  • 在产品 (customer_id) 上创建索引 customer_id_idx2
  • 在订单上创建索引 customer_id_revenues_idx(customer_id,revenues)
  • 在产品上创建索引 customer_id_costs_idx(customer_id,costs)

这是查询:

SELECT a.customer_id, (SUM(a.revenues) / SUM(b.costs) :: FLOAT) AS roi
FROM orders a
JOIN products b
ON a.customer_id = b.customer_id
WHERE a.customer_id IN (
    SELECT customer_id FROM (SELECT 
        customer_id,
        COUNT(*) AS n_products
    FROM products
    GROUP BY 1
    ORDER BY 2 DESC
    LIMIT 5) x
)
GROUP BY a.customer_id  
ORDER BY roi DESC

输出应返回前 5 名客户按他们购买的产品数量计算的收入/成本比率。

我正在使用 pgadmin。有人可以解释我如何加快速度并使其编译吗? 提前谢谢你。

【问题讨论】:

  • 请提供示例数据、期望的结果以及代码应该做什么的清晰解释。
  • edit您的问题并添加使用explain (format text)生成的execution plan(因为您无法运行explain (analyze) ) 为formatted text 并确保保留计划的缩进。粘贴文本,然后将``` 放在计划前一行和计划后一行。还请包括所有索引的完整 create index 语句。
  • 我正在尝试,但不幸的是我对 sql 和 stackoverflow 比较陌生,我不知道执行计划是什么。但我正在尝试像你说的那样编辑问题
  • @123_stack 您只需将explain 放在查询文本的前面,然后运行它。如果您使用的是 GUI 客户端,可能会有不同的方式,但如果您需要特定数据库客户端程序的建议,您需要告诉我们它是什么。
  • @jjanes:知道了,谢谢!

标签: sql postgresql performance join indexing


【解决方案1】:

据我所知,我认为您不需要汇总两次。

select customer_id, roi
from (
  select o.customer_id, 
         sum(o.revenues) / sum(p.costs)::float as roi, 
         count(*) as n_products
  from orders o
    join products p on o.customer_id = p.customer_id
  group by o.customer_id  
  order by n_products
  limit 5
) t
order by roi desc

或者尝试分别聚合两个表,然后将结果连接起来:

select o.customer_id, o.revenues / p.costs::numeric as roi
from (
  select customer_id, sum(revenues) as revenues
  from orders
  group by customer_id
) o
  join (
    select customer_id, sum(costs) as costs, count(*) n_products
    from products
    group by customer_id
  ) p on p.customer_id = o.customer_id
order by p.n_products desc
limit 5  

【讨论】:

  • 感谢您的回复!我尝试了您的解决方案,但问题仍然存在。几分钟后它仍在运行。不知道是内存问题还是索引问题。例如,当我尝试使用相同的查询但过滤特定的 customer_id(例如 WHERE customer_id = 779)而不是子查询时,它只需 5 秒即可编译。但是,在按产品筛选前 5 名客户时,它变得太慢了。
  • @123_stack:这里出了点问题。 orders 有多少行?
  • orders表有32000条记录,products表有150万条记录
  • @123_stack:我添加了另一个解决方案。
  • 您的新解决方案奏效了!无法告诉你我有多感激,非常感谢你。你能解释一下是什么导致了这个问题吗?我是 sql 新手,还有很多东西要学
猜你喜欢
  • 2015-10-04
  • 2011-01-13
  • 1970-01-01
  • 1970-01-01
  • 2014-04-05
  • 1970-01-01
  • 1970-01-01
  • 2011-08-18
  • 2012-04-19
相关资源
最近更新 更多