4
SELECT
    t1.theater_id,
    sum(t2.full_sale_price * t1.full_tickets + 
        t2.half_sale_price * t1.half_tickets) as Gross,
    sum(t2.full_cost_price * t1.full_tickets +
        t2.half_cost_price * t1.half_tickets) as Cost,
    Round(sum((t2.full_sale_price * t1.full_tickets + 
               t2.half_sale_price * t1.half_tickets) * t3.rate) / 100,
         2) as IPG,
         (sum(t2.full_sale_price * t1.full_tickets + 
              t2.half_sale_price * t1.half_tickets) 
              - Round(sum((t2.full_sale_price * t1.full_tickets + 
              t2.half_sale_price * t1.half_tickets) * (CASE
                WHEN ISNULL(t3.rate) THEN 0
                ELSE t3.rate
                END)) / 100,
            2)) as NetRev,
    CASE
        WHEN (t1.method = '2') THEN sum(0.00)
        ELSE 0
    END as sms,
    sum((CASE
        WHEN (t4.type = '1') THEN ((t1.full_tickets * 2) + (t1.half_tickets))
        ELSE (t1.full_tickets + t1.half_tickets)
    END) * 4.00) as maintenance,
    sum((((t2.full_sale_price * t1.full_tickets + 
           t2.half_sale_price * t1.half_tickets) 
           - (Round((t2.full_sale_price * t1.full_tickets + 
                     t2.half_sale_price * t1.half_tickets) * (CASE
                WHEN ISNULL(t3.rate) THEN 0
                ELSE t3.rate
            END) / 100,
            2))) - (t2.full_cost_price * t1.full_tickets + 
                    t2.half_cost_price * t1.half_tickets)) 
                    - (CASE
                       WHEN (t1.method = '2') THEN 0.00
                       ELSE 0
                       END) 
                    - (CASE
                       WHEN (t4.type = '1') THEN ((t1.full_tickets * 2) +
                                                  (t1.half_tickets))
                       ELSE (t1.full_tickets + t1.half_tickets)
    END) * 4.00) as admincost,
    sum(CASE
        WHEN (t4.type = '1') THEN ((t1.full_tickets * 2) + (t1.half_tickets))
        ELSE (t1.full_tickets + t1.half_tickets)
    END) as totTk
FROM
    `ratecard_rates` as t2 INNER JOIN
    `reservation` as t1 ON t1.movie_id = t2.movie_id
        AND t1.theater_id = t2.theater_id
        AND t1.showtime_id = t2.showtime_id
        AND t1.category_id = t2.category_id
        AND t1.bx_date = t2.date_apply
        LEFT JOIN
    `paymentgateway` as t3 ON t1.paymentgateway_id = t3.id
        LEFT JOIN
    `theatercategories` as t4 ON t1.category_id = t4.id
WHERE
    t1.status = '1' AND t1.method = '1'
        AND t1.reservation_type = '1'
        AND DATE(`tx_date`) BETWEEN DATE('2012-08-27') AND DATE('2012-08-27')
GROUP BY t1.theater_id

ここに説明があります 説明

4

2 に答える 2

2

"Using temporary; using filesort"通常、クエリプランのこの時点で、MySsqlは中間セットをディスクに書き込むことを決定します。これは、残念ながら、関連する列に配置したインデックスを常に使用できるとは限らないことを意味します。

私の経験では、これを回避する唯一の方法は、中間結果の設定サイズを小さくすることです。これが発生するポイントを特定してみてください。たとえば、全体SELECTをaに置き換えてCOUNT(*)、CASEビットなどを削除し、MySqlがディスクに「キャッシュ」したい2779行を生成しているものを確認します。

詳細については、この回答を参照してください。

于 2012-08-27T07:20:22.517 に答える
0

やみくもにインデックスを作成しましたか、それとも最初に実行計画を確認しましたか? CASE..END句は非常に役立ちますが、実行計画を台無しにすることがあります。このリンクを確認すると、私が話していることを理解するのに役立ちます。1 つのオプションは、ストアド プロシージャを作成し、このクエリを小さなクエリに分割することです。サブクエリが役立つ場合もあります。これは、試してみる別のオプションです。

于 2012-08-27T07:14:23.197 に答える