0

次のクエリを最適化する方法はありますか。約 11 秒かかります。

SELECT 
    concat(UNIX_TIMESTAMP(date), '000') as datetime, 
    TRUNCATE(SUM(royalty_price*conversion_to_usd*
             (CASE WHEN sales_or_return = 'R' THEN -1 ELSE 1 END)*
             (CASE WHEN royalty_currency = 'JPY' THEN .80 
                   WHEN royalty_currency in ('AUD', 'NZD') THEN .95 ELSE 1 END) )
    ,2) as total_in_usd
FROM 
    sales_raw 
GROUP BY
    date 
ORDER BY
    date ASC

私が得る説明を行う:

1   SIMPLE  sales_raw   index   NULL    date    5   NULL    735855  NULL
4

3 に答える 3

2

これを高速化できる場合があります。に索引があるようですdate。何が起こっているかというと、行がインデックスで読み取られ、次に各行が検索されます。データが日付フィールドで順序付けされていない場合、読み取りは基本的にランダムなページで行われるため、これは最適ではない可能性があります。元のテーブルがメモリに収まらない場合、 「ページ スラッシング」と呼ばれる状態が発生します。レコードが必要で、ページがメモリから読み取られ (メモリ キャッシュ内の別のページが置き換えられます)、次の読み取りでもキャッシュ ミスが発生する可能性があります。

これが発生しているかどうかを確認するには、次の 2 つのいずれかをお勧めします。(1) のインデックスを削除するか、基準を にdate切り替えてみてください。これらのいずれかで、要因としてインデックスを削除する必要があります。group byconcat(UNIX_TIMESTAMP(date), '000')

追加のコメントから、これは発生していませんが、インデックスの利点は小さいようです。

(2) インデックスを拡張して、クエリで使用されるすべてのテーブルを含めることもできます。インデックスには、日付のほかに、royalty_price、conversion_to_usd、sales_or_return、royalty_currency が含まれている必要があります。これにより、ページ内の追加情報を検索することなく、インデックスがクエリを完全に満たすことができます。

ハードウェアの機能に見合った十分な大きさのページ キャッシュがあることを DBA に確認することもできます。

于 2013-04-03T19:55:44.357 に答える
0

これは、結合さえも含まない単純なグループによるクエリです。問題は、使用している機能にあると思います。

日付と conversion_to_usd の合計を取得するだけの単純なクエリから始めてください。パフォーマンスをチェックし、常にパフォーマンスをチェックしながらクエリを段階的に構築します。犯人を特定するのにそれほど時間はかかりません。

連結は通常は遅い操作ですが、合計後の切り捨てがオプティマイザを混乱させるのではないかと思います。2 番目のケースは、通貨コードとそれぞれのパーセンテージのテーブルとの結合に依存することで置き換えることができますが、それが大きな違いを生むかどうかは明らかではありません。まず、犯人の操作を特定します。

値を正しい量で保存することもできますが、それは非正規化をもたらします。

于 2013-04-03T21:02:13.657 に答える