0

次のクエリでは、販売の最新のステータスを表示します (ステージごと、この場合は 3 番目)。クエリは、販売のステータス履歴のサブクエリに基づいています。

SELECT v.id_sale, 
IFNULL((
    SELECT (CASE WHEN IFNULL( vec.description, '' ) = ''
                    THEN ve.name
                    ELSE vec.description
                    END)
    FROM t_record veh
    INNER JOIN t_state_campaign vec ON vec.id_state_campaign = veh.id_state_campaign
    INNER JOIN t_state ve ON ve.id_state = vec.id_state
    WHERE veh.id_sale = v.id_sale
    AND vec.id_stage = 3
    ORDER BY veh.id_record DESC
    LIMIT 1
), 'x') sale_state_3
FROM t_sale v
INNER JOIN t_quarters sd ON v.id_quarters = sd.id_quarters
WHERE 1 =1
AND v.flag =1
AND v.id_quarters =4
AND EXISTS (
    SELECT '1'
    FROM t_record
    WHERE id_sale = v.id_sale
    LIMIT 1
)

クエリの遅延は0.0057segで、 1011 件のレコードが表示されます。

where句でサブクエリを繰り返す必要があるため、州の名前で売上をフィルタリングする必要があるため、結合を使用して同じクエリを変更することにしました。この場合、MAX 関数を使用して最新のステータスを取得しています。

SELECT
v.id_sale,
IFNULL(veh3.State3,'x') AS sale_state_3
FROM t_sale v
INNER JOIN t_quarters sd ON v.id_quarters = sd.id_quarters
LEFT JOIN (
    SELECT veh.id_sale, 
    (CASE WHEN IFNULL(vec.description,'') = '' 
        THEN ve.name
        ELSE vec.description END) AS State3
    FROM t_record veh
    INNER JOIN (
        SELECT id_sale, MAX(id_record) AS max_rating
                FROM(
                    SELECT veh.id_sale, id_record
                    FROM t_record veh
                    INNER JOIN t_state_campaign vec ON vec.id_state_campaign = veh.id_state_campaign AND vec.id_stage = 3
                ) m
            GROUP BY id_sale    
    ) x ON x.max_rating = veh.id_record
    INNER JOIN t_state_campaign vec ON vec.id_state_campaign = veh.id_state_campaign
    INNER JOIN t_state ve ON ve.id_state = vec.id_state
) veh3 ON veh3.id_sale = v.id_sale
WHERE v.flag = 1
AND v.id_quarters = 4

このクエリは、同じ結果 (1011) を示します。しかし、問題は0.0753秒かかることです

可能性を検討すると、クエリの速度に違いをもたらす要因が見つかりました。

AND EXISTS (
    SELECT '1'
    FROM t_record
    WHERE id_sale = v.id_sale
    LIMIT 1
)

この句を削除すると、両方のクエリで同じ時間の遅延が発生します...なぜうまくいくのですか? 結合でこの句を使用する方法はありますか? あなたの助けを願っています。

編集

各クエリの EXPLAIN の結果をそれぞれ表示します。

q1: ここに画像の説明を入力

q2: ここに画像の説明を入力

4

1 に答える 1

0

興味深いことに、この小さなステートメントは基本的に、t_record.id_sale と t_sale.id_sale の間に一致があるかどうかを判別します。

これにより、クエリの実行が高速化されるのはなぜですか? Where ステートメントは select ステートメントの subSelects の前に適用されるため、販売に伴うレコードがない場合は、subSelect を処理する必要はありません。これはあなたをしばらくの間ネッティングしています。だからこそ、よりよく機能します。

結合構文で機能しますか? テストするテーブルがなければ、実際にはわかりませんが、いつでも最後に適用して調べることができます。キーワード EXPLAIN をクエリの先頭に追加すると、最適化に役立つ実行計画が得られます。おそらく、結合構文でより良い結果を得る最善の方法は、テーブルにいくつかのインデックスを追加することです。

しかし、私はあなたに尋ねます、これは必要ですか?100 分の 8 秒未満で返されるクエリがあります。このクエリが 1 時間に何千回も実行されない限り、これは実際には DB にまったく負担をかけず、アプリケーションの他の場所で改善を行うために時間を費やしたほうがよいでしょう。

于 2012-10-17T18:59:09.583 に答える