下面是我的 MySQL 查询,用于查找每个帐户的连续日期之间的差异,然后使用结果准备频率计数表。这个查询当然非常慢,但在此之前我做的事情正确吗?如果可以的话请帮忙。还嵌入了一个小数据样本。 珍惜您的时间。 奥祖哈
ID DATE
403 2008-06-01
403 2012-06-01
403 2011-06-01
403 2010-06-01
403 2009-06-01
15028 2011-07-01
15028 2010-07-01
15028 2009-07-01
15028 2008-07-01
SELECT
month_diff,
count(*)
FROM
(SELECT t1.id,
t1.date,
MIN(t2.date) AS lag_date,
TIMESTAMPDIFF(MONTH, t1.date, MIN(t2.date)) AS month_diff
FROM tbl_name T1
INNER JOIN tbl_name T2
ON t1.id = t2.id
AND t2.date > t1.date
GROUP BY t1.id, t1.date
ORDER BY t1.id, t1.date
)
GROUP BY month_diff
ORDER BY month_diff
最佳答案
可能,实现内联 View 需要花费大部分时间。确保有合适的索引可用于提高连接操作的性能;覆盖索引 ON tbl_name (id, date)
可能是此查询的最佳选择。
有了合适的索引(如上所述),可以通过如下查询获得更好的性能:
SELECT d.month_diff
, COUNT(*)
FROM ( SELECT IF(@prev_id = t.id
, TIMESTAMPDIFF(MONTH, t.date, @prev_date )
, NULL
) AS month_diff
, @prev_date := t.date
, @prev_id := t.id
FROM tbl_name t
CROSS
JOIN (SELECT @prev_date := NULL, @prev_id := NULL) i
GROUP BY t.id DESC, t.date DESC
) d
WHERE d.month_diff IS NOT NULL
GROUP BY d.month_diff
请注意,不保证 MySQL 用户定义变量的使用。但我们确实观察到以特定方式编写的查询的一致行为。 (MySQL 的 future 版本可能会改变我们观察到的行为。)
<小时/>编辑:我修改了上面的查询,将 ORDER BY t.id, t.date
替换为 GROUP BY t.id, t.date
.. . 从示例数据中并不清楚 (id,date)
是否保证唯一。 (如果我们确实有这样的保证,那么我们就不需要 GROUP BY,我们可以只使用 ORDER BY。否则,我们需要 GROUP BY 来获得与原始查询返回的相同结果。 )
关于MySQL 查询很慢 - 组级别的连续日期存在差异,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26046297/