考虑以下架构:
Tables: Tasks (tid, jobid, status, name)
Jobs(jobid, submitTime)
这里我可以有多个任务表行和一个jobid。现在我想从Tasks表中获取所有行,使得它们的状态= 5,而具有相同jobid的所有其他行也应该是5。
例如:我在任务中有5行,前2个有jobid = 1,状态= 5,最后3个有jobid = 2,两个有status = 5,1有status = 4。我的查询应该只返回jobid = 1的前两行,因为jobid = 1的所有行的status = 5。不应返回jobid = 2的行,因为jobid = 2的一行的status = 4。
假设我在Tasks表中有300K行,我需要帮助构建优化查询。
mysql> select * from task;
+--------+-------+--------+----------------------+
| taskid | jobid | status | name |
+--------+-------+--------+----------------------+
| 1 | 1 | 5 | Task 1, Job 1 |
| 2 | 1 | 5 | Task 2, Job 1 |
| 3 | 2 | 5 | Task 3, Job 2 |
| 4 | 2 | 5 | Task 4, Job 2 |
| 5 | 2 | 4 | Task 5, Job 2 status |
+--------+-------+--------+----------------------+
5 rows in set (0.00 sec)
mysql> select * from job;
+-------+---------------------+
| jobid | time |
+-------+---------------------+
| 1 | 2016-07-15 15:13:42 |
| 2 | 2016-07-15 15:13:44 |
+-------+---------------------+
我需要的输出:
+--------+-------+--------+----------------------+
| taskid | jobid | status | name |
+--------+-------+--------+----------------------+
| 1 | 1 | 5 | Task 1, Job 1 |
| 2 | 1 | 5 | Task 2, Job 1 |
答案 0 :(得分:0)
SELECT *
FROM tasks t
WHERE t.`status` = 5
AND NOT EXISTS (
SELECT 1
FROM tasks tt
WHERE t.jobid = tt.jobid
AND tt.`status` <> 5
)
输出:
+-----+-------+--------+---------------+
| tid | jobid | status | name |
+-----+-------+--------+---------------+
| 1 | 1 | 5 | Task 1, Job 1 |
| 2 | 1 | 5 | Task 2, Job 1 |
+-----+-------+--------+---------------+
2 rows in set
最重要的是考虑在status
和jobid
列添加索引:
ALTER TABLE `tasks`
ADD INDEX `status_IDX` (`status`),
ADD INDEX `jobid_IDX` (`jobid`);
或者更好的是两个字段中只有一个复合索引:
ALTER TABLE `tasks`
ADD INDEX `composite_IDX` (`status`,`jobid`);
您将选择哪个索引取决于您将对该表执行哪种查询。在这种特殊情况下,复合材料是更好的选择。
答案 1 :(得分:0)
您可以使用LEFT JOIN
对同一个表执行此操作,该表将加入status <> 5
的所有记录。
然后,您可以排除从此JOIN
获得结果的任何记录。
事实上,在status
和jobid
上添加索引可以提高效果。
SELECT t.taskid, t.jobid, t.status, t.name
FROM task t
LEFT JOIN task t2
ON t.jobid = t2.jobid
AND t.taskid <> t.taskid
AND t.status <> 5
WHERE t.status = 5
AND t2.taskid IS NULL
GROUP BY t.taskid
让我知道这是否有效! 祝你好运:)