我们在这个查询中只有一个包含数百万行的表,因为在缓冲池大小为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
答案 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