Mysql Group By和Sum性能问题

时间:2017-07-19 18:26:40

标签: mysql

我们在这个查询中只有一个包含数百万行的表,因为在缓冲池大小为25G的服务器上运行需要138秒,服务器本身是带有SSD驱动器的Linux。

我想知道是否有人可以建议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 

1 个答案:

答案 0 :(得分:2)

我看到了一些明显的改进。

<强>子选择

不要使用subselect。这不是一件大事,但在这里增加开销是没有意义的。

使用区别

这里真的需要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