0

非常に非効率的な作業クエリがあります。それを改善する簡単な方法が欠けているのではないかと思っています。

簡単なテーブル:

ID 日付 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 の他の行にそれ以前の日付がないすべての行を取得します。すべての結果を日付順に並べます。

グループ単位の最小サブクエリを使用して 2 番目の WHERE 条件を作成する現在のクエリ。

選択する *
FROM `テスト`
WHERE `master_id` =0
OR `id` IN (

    SELECT test.`id`
    から (
        SELECT `master_id`, MIN(`date`) AS マインドデート
        FROM `テスト`
        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 `日付`

動作しますが、EXPLAIN を使用すると非効率的に見えます。

id select_type テーブル タイプ possible_keys キー key_len ref 行 エクストラ
-------------------------------------------------- -------------------------------------------------- ----------
1 PRIMARY テスト ALL NULL NULL NULL NULL 8 where を使用。ファイルソートの使用
2 DEPENDENT SUBQUERY 派生3 システム NULL NULL NULL NULL 1   
2 DEPENDENT SUBQUERY test eq_ref PRIMARY PRIMARY 4 func 1 where の使用
3 DERIVED テスト ALL NULL NULL NULL NULL 8 where を使用。一時的な使用; ファイルソートの使用

これを改善できますか?ID=0 用と groupwise min 用の 2 つのクエリに分割する必要がありますか? 前もって感謝します。

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 に答える