我有一个看起来非常低效的工作查询;我想知道我是否错过了改进它的简单方法。
简单表:
id date master_id ------------------------- 1 2015-02-01 0 2 2015-02-02 0 3 2015-02-03 0 4 2015-02-04 1 5 2015-02-02 1 6 2015-02-17 1 7 2015-02-27 1 8 2015-01-01 1
目标:获取master_id为零的所有行,或者master_id不为零,并且同一master_id的其他行没有更早的日期。按日期订购每个结果。
当前查询,使用groupwise minimum子查询创建第二个WHERE条件。
SELECT * FROM `test` WHERE `master_id` =0 OR `id` IN ( SELECT test.`id` FROM ( SELECT `master_id`, MIN(`date`) AS mindate FROM `test` WHERE `master_id` 0 GROUP BY `master_id` ) AS x INNER JOIN `test` ON x.`master_id` = test.`master_id` AND x.mindate= test.`date` ) ORDER BY `date`
它可以工作,但是EXPLAIN使它看起来效率低下:
id select_type table type possible_keys key key_len ref rows Extra ------------------------------------------------------------------------------------------------------------- 1 PRIMARY test ALL NULL NULL NULL NULL 8 Using where; Using filesort 2 DEPENDENT SUBQUERY derived3 system NULL NULL NULL NULL 1 2 DEPENDENT SUBQUERY test eq_ref PRIMARY PRIMARY 4 func 1 Using where 3 DERIVED test ALL NULL NULL NULL NULL 8 Using where; Using temporary; Using filesort
我可以改善吗?我应该把它分成两个查询,一个用于ID = 0,一个用于分组分钟?提前谢谢。
答案 0 :(得分:0)
避免内部联接可以改善查询:
SELECT *
FROM `test`
WHERE `master_id` =0
OR `id` IN (
SELECT t1.id
FROM (SELECT *
FROM test t2
WHERE t2.master_id!=0
ORDER BY t2.date ASC) t1
GROUP BY t1.master_id
)
ORDER BY `date`;
答案 1 :(得分:0)
这个怎么样......
SELECT * FROM test WHERE master_id = 0
UNION
SELECT x.*
FROM test x
JOIN (SELECT master_id,MIN(date) min_date FROM test GROUP BY master_id) y
ON y.master_id = x.master_id
AND y.min_date = x.date;