因此,我有三个表:用户,购买A和采购B。我想找到所有的用户谁已经购买任何在加入后的前30天。因此,所有从购买A或购买B的用户在created_at后的前30天内购买。
有几件事要注意:
用这么大的表来处理这个问题,最好的方法是什么?我知道我可以用两个剩下的联接来完成这个任务,但是我不需要购买表中的所有行,我只需要知道是否存在。
SELECT
user_id
,name
,created_at
FROM
users u
LEFT JOIN purchases_a pa
ON u.user_id = pa.user_id AND TO_DATE(pa.purchase_date) <= DATEADD(DAY, 30, u.created_at)
LEFT JOIN purchases_b pb
ON u.user_id = pb.user_id AND TO_DATE(pb.purchase_date) <= DATEADD(DAY, 30, u.created_at)在这里,一个连接甚至是正确的方法,还是将在或存在更合适?

发布于 2022-04-21 21:57:47
对这么大的数据集的查询一定要花费很长的时间,不管您如何优化它。你正在做一个2亿用户的表格扫描!光是这一点就会付出代价,更不用说加入了。
底线是,使用为OLTP工作优化的数据库技术,这不是针对该规模的规范化数据库运行的查询。
也许它可以在数据仓库上完成,但不能在MySQL上完成。即使在数据仓库上,也应该转换数据以支持特定的报告。
您可以做的一种方法(在MySQL上或在DW上)是稍微去修饰,方法是向users表添加一个属性,该属性存储一个布尔值,如果每个用户在创建日期后30天内购买了该属性,则该属性对每个用户来说都是正确的。然后可以索引该布尔列。查询可以在不检查2亿行的情况下给出结果。
当用户进行购买时,如果在创建日期后30天内将布尔列更新为true,则代码会将其更新为true。
您还应该考虑分片,所以并不是所有的用户和他们的购买都存储在一个数据库中。MySQL可以处理数十亿行,但很难在这种规模上对查询进行优化。无论如何,将数据拆分到多个MySQL服务器上很快就变得必要了。如果这样做,那么每个服务器只需要报告自己的数据子集,这样就可以在并行线程中运行报表,然后组合结果。
https://stackoverflow.com/questions/71960606
复制相似问题