2017-07-19 15 views
1

このクエリのバッファプールサイズが25Gのサーバーでは、このクエリの実行に138秒かかり、サーバー自体がLinuxでSSDドライブを使用する数百万行のテーブルが1つしかありません。MysqlグループのBy and Sumパフォーマンスの問題

誰かが、MySQLの設定や実行時間を短縮するクエリ自体の改善を示唆しているのではないかと思います。このパフォーマンスの問題を抱える8つの大きなmember_idのみがあり、残りは5秒未満で実行されます。ロールアップレポートでは、このように複数のサマリーテーブルを実行します。

select * 
from (
SELECT distinct account_name AS source,SUM(royalty_amount) AS total_amount 
FROM royalty_stream 
WHERE member_id = '1050705' 
    AND deleted = 0 
    AND period_year_quarter >= '2016_Q1' 
    AND period_year_quarter <= '2016_Q2'  
GROUP BY account_name 
ORDER BY total_amount desc 
LIMIT 1 
) a 
+0

関与テーブルのスキーマは何ですか? – Jacobm001

+0

Explain出力とは何ですか? – Jacobm001

+0

'GROUP BY'クエリの' DISTINCT'の目的は何ですか? – axiac

答えて

2

私はいくつかの明らかな改善を見ます。

サブセレクト

は、副選択を使用しないでください。これは大きな問題ではありませんが、オーバーヘッドを追加するのはほとんど意味がありません。個別

を使用して

は本当にここで必要distinctですか?グループ化しているので、不要なオーバーヘッドになるはずです。

データストレージプラクティス

あなたperiod_year_quarter評価がハードルになるだろう。ストリングの比較は、残念ながらあなたができるより遅いものの1つです。データ構造を更新する能力があれば、period_year_quarterを2つの異なる整数フィールドに分割することを強くお勧めします。今年は1つ、四半期は1つ。

royalty_amountは実際に数値として格納されていますか、またはデータベースで毎回暗黙的に変換されていますか?そうであれば(驚くほど一般的な間違いのように)数値に変換することも役に立ちます。あなたはこのテーブルの上にあるどのようなインデックスを説明していない

インデックス

。私はあなたが少なくともmember_idに1つ持っていることを望んでいます。もしそうでなければ、それは必ず索引付けされるべきです。

(member_id, period_year_quarter)のインデックスをさらにお勧めします。あなたが前のセクションから私のアドバイスを受けたなら、それは(member_id, year, quarter)でなければなりません。


select 
    account_name as source 
    , sum(royalty_amount) as total_amount 
from 
    royalty_stream 
where 
    member_id    = '1050705' 
    and deleted    = 0 
    and period_year_quarter between '2016_Q1' and '2016_Q2' 
group by 
    account_name 
order by 
    total_amount desc 
limit 1 
+0

私はまた、index_nameでaccount_nameを試してみます。データだけがそれが良い考えであるかどうかを伝えます。 –

+0

@SamHartman:それを独自のインデックスに入れます。あなたがそれに適格ではないので、それはインデックスから大いに利益を得ることはありません。 – Jacobm001

+0

文字列の比較は大きな障害ではありません。索引を正しく使用することが最も重要ですが、他の点はすべて有効です。 – Strawberry

関連する問題