0

我有一个工作查询似乎非常低效;我想知道我是否缺少一种改进它的简单方法。

简单表:

身份证日期 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 的其他行有更早的日期。按日期排序每个结果。

当前查询,使用分组最小子查询来创建第二个 WHERE 条件。

选择 *
从`测试`
WHERE `master_id` =0
或 `id` IN (

    选择测试。`id`
    从 (
        SELECT `master_id`, MIN(`date`) AS mindate
        从`测试`
        WHERE `master_id` 0       
        按“master_id”分组
    ) 作为 x
    INNER JOIN `test` ON x.`master_id` = test.`master_id`
    AND x.mindate=test.`date`
)
按“日期”排序

它有效,但 EXPLAIN 使它看起来效率低下:

id select_type table type possible_keys key key_len ref rows Extra
-------------------------------------------------- -------------------------------------------------- ---------
1 PRIMARY 测试 ALL NULL NULL NULL NULL 8 使用 where;使用文件排序
2 DEPENDENT SUBQUERY 派生3 系统 NULL NULL NULL NULL 1   
2 DEPENDENT SUBQUERY 测试 eq_ref PRIMARY PRIMARY 4 func 1 使用 where
3 DERIVED 测试 ALL NULL NULL NULL NULL 8 使用 where;使用临时的;使用文件排序

我可以改进这个吗?我应该把它分成两个查询,一个用于 ID=0,一个用于分组最小值?提前致谢。

4

2 回答 2

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`;
于 2015-02-12T17:51:04.280 回答
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;
于 2015-02-12T17:52:57.670 回答