与group by的大型mysql查询

时间:2015-01-10 03:13:40

标签: mysql

我有一张有5亿条记录的定价历史表。它的格式如下:

Id, sku, vendor, price, datetime

我想要做的是在特定日期范围内按供应商获取所有产品的平均价格。大多数产品每3天更新一次,但会有所不同。

所以,这是我要运行的查询:

SELECT 
    avg(price) 
FROM table 
WHERE 
    vendor='acme' 
    AND datetime > '12-15-2014' 
    AND datetime < '12-18-2014' 
GROUP BY sku

这3天的范围足够宽,我肯定会得到至少一个价格样本,但是一些skus可能已被多次采样,因此分组尝试只获得每个sku的一个实例。

问题是,此查询运行并运行,似乎没有完成(超过15分钟)。有大约500k独特的skus。

有什么想法吗?

编辑:更正了asin到sku

2 个答案:

答案 0 :(得分:1)

要通过mysql优化此查询,您需要创建一个复合索引

(vendor, datetime, asin)

在此特定订单中(它为床垫)

还值得尝试创建另一个

(vendor, datetime, asin, price)

因为可能表现更好(因为它是所谓的&#34;覆盖索引&#34;)。

具有其他顺序的索引(例如(datetime, vendor)(在另一个答案中建议))是无用的,因为datetime用于范围比较。

很少注意到:

  • 如果仅vendor='acme' AND datetime > '12-15-2014' AND datetime < '12-18-2014'过滤条件涵盖整个表格的一小部分(比如少于10%),则索引会很有用。
  • Mysql不支持dd-mm-yyyy文字(至少没有记录,请参阅参考资料)所以我认为它必须是yyyy-mm-dd而不是
  • 您的比较不包括2014年12月15日的第一秒。所以您可能需要datetime >= '2014-12-15'代替。

参考文献:

答案 1 :(得分:0)

您需要一个索引来支持您的查询。建议您在供应商和日期时间上创建索引,如下所示:

CREATE INDEX pricing_history_date_vendor ON pricing_history (datetime, vendor);

此外,我假设您希望按sku而不是未定义的列asin进行分组。

更不用说评论中其他人指出的非标准SQL日期格式MM-dd-yyyy(应该是yyyy-MM-dd)。