【发布时间】:2013-02-21 13:56:04
【问题描述】:
根据我最近的问题Select information from last item and join to the total amount,我在生成表时遇到了一些内存问题
我有两张表 sales1 和 sales2 像这样:
标识 |日期 |客户 |出售
有了这个表定义:
CREATE TABLE sales (
id int auto_increment primary key,
dates date,
customer int,
sale int
);
sales1 和 sales2 具有相同的定义,但 sales2 在每个字段中都有 sale=-1。客户可以不在一个表中,也可以在一个表中或两个表中。这两个表都有大约 300.000 条记录和比这里指出的更多的字段(大约 50 个字段)。他们是 InnoDB。
我想为每个客户选择:
- 购买次数
- 最后一次购买价值
- 购买的总金额,当它具有正值时
我使用的查询是:
SELECT a.customer, count(a.sale), max_sale
FROM sales a
INNER JOIN (SELECT customer, sale max_sale
from sales x where dates = (select max(dates)
from sales y
where x.customer = y.customer
and y.sale > 0
)
)b
ON a.customer = b.customer
GROUP BY a.customer, max_sale;
问题是:
我必须得到某些计算所需的结果,按日期分开:2012 年的信息、2013 年的信息,还有所有年份的信息。
如果我只做一年,存储所有信息大约需要 2-3 分钟。
但是当我尝试收集这些年来的信息时,数据库崩溃了,我收到如下消息:
InternalError: (InternalError) (1205, u'Lock wait timeout exceeded; try restarting transaction')
似乎连接如此庞大的表对于数据库来说太多了。当我explain查询时,几乎所有百分比的时间都来自creating tmp table。
我想把收集的数据分成四份。我们每三个月获得一次结果,然后加入并对其进行排序。但我想这个最终的连接和排序对于数据库来说又是太多了。
那么,只要我不能更改表结构,您的专家会建议如何优化这些查询?
【问题讨论】:
-
你是如何加入表格的?您不会将 300,000 行交叉连接在一起,是吗?那将是 900 亿行...
-
但不知何故很棒
-
300,000 行的表绝对不算大。
-
我们需要看到分解的select语句;或者你可以使用解释计划来确定你的滞留在哪里。您确实有日期和客户的索引,对吗?
标签: mysql sql performance optimization greatest-n-per-group