2017-07-19 86 views
1

我們只有一個包含數百萬行的表,其中此查詢需要138秒的時間才能在緩衝池大小爲25G的服務器上運行,服務器本身使用的是帶有SSD驅動器的Linux。Mysql Group By和性能問題

我想知道是否有人可以建議任何改進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

解釋輸出是什麼? – Jacobm001

+0

「GROUP BY」查詢中DISTINCT的用途是什麼? – axiac

回答

2

我看到了一些明顯的改進。

子選擇

不要使用子查詢。這不是一個大問題,但在這裏增加開銷是沒有意義的。

使用鮮明

是在distinct這裏真正需要的?由於你正在分組,它應該是不必要的開銷。

數據存儲實踐

period_year_quarter評估將是一個障礙。不幸的是,字符串比較是你能做的較慢的事情之一。如果您有能力更新數據結構,我強烈建議您將period_year_quarter分解爲兩個不同的整數字段。一年一季,一季季。

是royalty_amount實際存儲爲一個數字,還是你讓數據庫隱式轉換它每次?如果是這樣(令人驚訝的常見錯誤)將其轉換爲數字也將有所幫助。

索引

你沒有解釋是在此表中哪些索引。我希望你至少在member_id上有一個。如果不是,它肯定應該被索引。

我會進一步推薦(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

我也試着在索引中使用account_name。只有數據會告訴我們這是不是一個好主意。 –

+0

@SamHartman:把它放在自己的索引中。既然你不符合資格,它不會從索引中獲得巨大的收益。 – Jacobm001

+0

字符串比較沒有太大的障礙。索引的正確使用是最重要的 - 但你的其他觀點都是有效的。 – Strawberry