2016-07-15 190 views
0

は、スキーマの下に考えてみましょう:が最適化された選択クエリを必要

Tables: Tasks (tid, jobid, status, name) 
     Jobs(jobid, submitTime) 

ここで私は、1つのジョブIDで複数のタスクテーブルの行を持つことができます。今度は、Tasksテーブルからすべての行をステータス= 5とし、同じjobidを持つ他のすべての行も5にする必要があります。

例:私はjobidに1行とstatus = 5、最後の3つはjobid = 2であり、2つはステータス= 5でステータスが4であるものです。 jobid = 1の行はすべてステータス= 5なので、私のクエリではjobid = 1の最初の2行しか返されません。 jobid = 2の行がステータス= 4のため、jobid = 2の行は戻されません。

私は、タスクテーブルに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

'jobs'テーブルはあなたの質問にどのように関連していますか? – mitkosoft

+0

@TimBiegeleisen –

答えて

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 
) 

出力:

ALTER TABLE `tasks` 
    ADD INDEX `status_IDX` (`status`), 
    ADD INDEX `jobid_IDX` (`jobid`); 
:その上で

+-----+-------+--------+---------------+ 
| tid | jobid | status | name   | 
+-----+-------+--------+---------------+ 
| 1 |  1 |  5 | Task 1, Job 1 | 
| 2 |  1 |  5 | Task 2, Job 1 | 
+-----+-------+--------+---------------+ 
2 rows in set 

statusjobid列に索引を追加することを検討します両方のフィールドを超える

それとも、より良いだけで1複合インデックス:

ALTER TABLE `tasks` 
    ADD INDEX `composite_IDX` (`status`,`jobid`); 

あなたが選択するインデックスを使用すると、そのテーブルに対して実行されますクエリの種類に依存します。この特定のケースでは、コンポジットがより良い選択です。

+0

いいえ、これは最も良いでしょう: 'INDEX(jobid、status)'と 'INDEX(status)'。 –

0

status <> 5を持つすべてのレコードに参加する同じテーブルにLEFT JOINを指定すると、これを行うことができます。 これで、結果が得られたレコードを除外することができます。JOIN

実際、statusjobidにインデックスを追加すると、パフォーマンスが向上します。

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 

この機能が動作している場合はお知らせください。 幸運:)

+0

これには 'INDEX(jobid)'と 'INDEX(status、taskid)'が必要です。 –

関連する問題