以下是大约76秒的查询。
有没有办法对此进行优化?
仅供参考我已将id和日期字段编入索引。
对不起,我应该解释一下:
我有一堆id,日期和条件(= 1或0)。
我收集条件为1的ID和日期,结果如此 组说,然后查询Group1以选择最小日期。
然后,此最小日期用于将Group1中的帐户标记为1(如果是) 日期大于最短日期。
我希望这会有所帮助。我为第一次简洁而道歉。
SELECT
o.id,
o.date,
IF(o.date > m.min_date,1,0) b
FROM tab o
JOIN (SELECT DISTINCT
(id),
MIN(DATE) min_date
FROM tab
WHERE cond = 1
GROUP BY id) m
USING (id)
WHERE o.id = m.id
ORDER BY o.id,o.date
答案 0 :(得分:2)
您的原始查询并没有在表格中名为id
的任何字段上使用唯一键,这是一种奇怪的做法,看起来您似乎在追求以下内容:
SELECT o.id,
o.date,
m.date IS NULL b
FROM tab o
LEFT JOIN (
SELECT account_id, MIN(date) min_date
FROM tab
WHERE cond=1
GROUP BY account_id
) m
ON m.account_id = o.account_id
AND m.min_date = o.date
ORDER BY o.id, o.date
这应该很快。对于内部分组(account_id, date)
,您可以在SELECT
上使用复合索引。
以下是您不知道的一些提示:
DISTINCT
对所有选定的列进行操作,DISTINCT(id), MIN(date) min_date
将为您提供id和min_date的所有不同组合,ID本身可能会重复,并且其周围的括号为无意义的。也无法将DISTINCT
的行为更改为仅处理所选列的子集。SELECT id, MIN(date) ... GROUP BY account_id
不会始终返回与account_id组中的最小日期对应的ID。返回的id可以是组中任何未确定的ID。您需要JOIN
行到最小日期或使用其他方法来查找相应的ID。您接受的Mazster答案有一个奇怪的GROUP BY
和不必要的IF
条款。我已经在下面重写了它,以防这对你有所帮助,但如果它比我上面更新的那个更快,因为它运行每行的子查询,我感到很惊讶。您最好检查每个EXPLAIN
计划,因为我相信您可以使用上述查询更快地获得它:
SELECT o.id,
o.date,
o.date > (
SELECT MIN(DATE) min_date
FROM tab m
WHERE m.cond = 1
AND m.id = o.id
AND m.account_id = o.account_id
) b
FROM tab o
ORDER BY o.id,o.date
答案 1 :(得分:1)
我可以看到有自我加入,如何摆脱它?例如:
SELECT
o.id,
o.date,
IF(
(SELECT
MIN(DATE) min_date
FROM tab m
WHERE cond = 1 AND o.id = m.id
GROUP BY account_id
) < o.date,1,0
) b
FROM tab o
ORDER BY o.id,o.date