0

CASES 内でいくつかのカウントを使用して、2 つのクエリ結果変数のランキング値を作成しています。

次のコードは、実際にはより大きなクエリ内の左外部結合であり、ご想像のとおり、処理が少し遅くなります。これを改善する方法はありますか?私は今、このコードを何時間も調べています。助けていただければ幸いです。

SELECT
U.id,
COUNT(C.assets_animal_name REGEXP 'cats|dogs|birds|rats|horses|cows') AS leMatchesCount,

COALESCE( 
    (CASE 
        WHEN COUNT(C.assets_animal_name REGEXP 'cats|dogs|birds|rats|horses|cows') = 6 THEN 3.33
        WHEN COUNT(C.assets_animal_name REGEXP 'cats|dogs|birds|rats|horses|cows') = 5 THEN 2.75 
        WHEN COUNT(C.assets_animal_name REGEXP 'cats|dogs|birds|rats|horses|cows') < 5 AND COUNT(C.assets_animal_name REGEXP 'cats|dogs|birds|rats|horses|cows') >= 2 THEN 1.11
        WHEN COUNT(C.assets_animal_name REGEXP 'cats|dogs|birds|rats|horses|cows') = 1 THEN 0.55
    END)
, 0) AS leRank1,

IF(MATCH(C.assets_animal_name) AGAINST ("any animal" IN BOOLEAN MODE), 1.11,
COALESCE(
    (CASE 
        WHEN COUNT(C.assets_animal_name REGEXP 'cats|dogs|birds|rats|horses|cows') = 6 THEN 1.11
        WHEN COUNT(C.assets_animal_name REGEXP 'cats|dogs|birds|rats|horses|cows') = 5 THEN 0.88 
        WHEN COUNT(C.assets_animal_name REGEXP 'cats|dogs|birds|rats|horses|cows') < 5 AND COUNT(C.assets_animal_name REGEXP 'cats|dogs|birds|rats|horses|cows') >= 2 THEN 0.37
        WHEN COUNT(C.assets_animal_name REGEXP 'cats|dogs|birds|rats|horses|cows') = 1 THEN 0.18
        END)
, 0)) AS leRank2

FROM
us3r U

LEFT OUTER JOIN assets_animals C ON
C.user_id = U.id AND C.assets_animal_name IN ('cats','dogs','birds','rats','horses','cows')

GROUP BY
U.id

編集1:

クエリはオンザフライで作成され、ランキングに使用されるパラメーターの数がわかりません。

CASE 内では、4 つの WHEN 行のそれぞれが動的な数値 (ここでは 6) との一致を試み、各一致を次のように評価します (計算はサーバー側で行われ、これは論理出力です)

WHEN = 6 rank = 5.00
WHEN = (6-1) rank = 3.80
WHEN < (6-1) AND > 2 = 2.90
WHEN = 1 rank = 1.11

3 行目で、コードは"<"以前の値 BUT ">" 2をチェックすることに注意してください。

Ross Smith IIが指摘したように、WHEN の外で COUNT を使用すると、WHEN 内で「<」などのオペランドを使用できなくなります。

最初の 2 つと最後の WHEN については、比較記号は必要ありません。つまり、10 ではなく 6 カウントできるので、各 CASE は次のようになります。

COALESCE( 
    (CASE COUNT(C.assets_animal_name IN ('cats','dogs','birds','rats','horses','cows'))
        WHEN 6 THEN 3.33
        WHEN 5 THEN 2.75 
        WHEN COUNT(C.assets_animal_name IN ('cats','dogs','birds','rats','horses','cows') < 5 AND COUNT(C.assets_animal_name IN ('cats','dogs','birds','rats','horses','cows') >=2 THEN 1.11
        WHEN 1 THEN 0.55
    END)
, 0) AS leRank1,

この単純な変更により、貴重な数ミリ秒が節約されました。ありがとう。

編集2:

つかれた。「WHEN の外で COUNT を使用すると、WHEN 内でオペランドを使用することはできません」と書きました。つまり、上記の例では、一致するレコードが 0 件の場合に 3 行目が true になることを意味します。

編集3:

C structure: id(INT,P),assets_animal_name(VARCHAR), uid(FK->U)
U structure: id(INT,P), email(VARCHAR)

サンプルデータ:

C
1,cats,1
2,dogs,1
3,birds,1
4,birds,2
5,rats,2
6,horses,2
7,cows,2
8,cats,2

U
1, jdoe@aol.com
2, mjoe@aol.com

REGEXP '^(cats|dogs|birds|rats|horses|cows)$' の結果データ:

1, 5, 2.75, 0.88
2, 3, 1.11, 0.37  
4

1 に答える 1

0

初め、

REGEXP 'cats|dogs|birds|rats|horses|cows'

bratsと同様に一致しますrats。あなたはおそらく欲しい:

IN ('cats','dogs','birds','rats','horses','cows')

多分

REGEXP '^(cats|dogs|birds|rats|horses|cows)$' 

次に、 に置き換えるCASE WHEN xCASE x WHEN、少し簡単になります。

最後に、実際にはテーブルを結合していないため、最後の JOIN 句を WHERE に移動します。

書き換えられたクエリは次のとおりです。

SELECT
    U.id,
    COUNT(C.assets_animal_name IN ('cats','dogs','birds','rats','horses','cows')) AS leMatchesCount,
    COALESCE( 
        (CASE COUNT(C.assets_animal_name IN ('cats','dogs','birds','rats','horses','cows'))
            WHEN 6 THEN 3.33
            WHEN 5 THEN 2.75 
            WHEN 4 THEN 1.11
            WHEN 3 THEN 1.11
            WHEN 2 THEN 1.11
            WHEN 1 THEN 0.55
        END)
    , 0) AS leRank1,
    IF(MATCH(C.assets_animal_name) AGAINST ("any animal" IN BOOLEAN MODE), 1.11,
    COALESCE(
        (CASE COUNT(C.assets_animal_name IN ('cats','dogs','birds','rats','horses','cows'))
            WHEN 6 THEN 1.11
            WHEN 5 THEN 0.88 
            WHEN 4 THEN 0.37
            WHEN 3 THEN 0.37
            WHEN 2 THEN 0.37
            WHEN 1 THEN 0.18
            END)
    , 0)) AS leRank2
FROM
    us3r U
LEFT OUTER JOIN 
    assets_animals C ON
        C.user_id = U.id
WHERE           
    C.assets_animal_name IN ('cats','dogs','birds','rats','horses','cows')
GROUP BY
    U.id

それがパフォーマンスに役立つかどうかをお知らせください。

于 2012-10-15T02:21:14.363 に答える