表有100 000条记录,使用聚合函数需要20-21秒。如何优化此查询?
SELECT source, sum(product_price*quantity) AS price
FROM `sheet`
WHERE source !=''
GROUP BY source
ORDER BY `price` DESC
我还在表格中使用了索引
ALTER TABLE `dbname`.`sheet` ADD INDEX `reprting_module` (`source`(30));
这是解释查询后的输出
答案 0 :(得分:1)
首先,您要求MySQL服务器在此查询中进行一些计算,然后对结果进行排序。这需要一些时间。它必须检查表格的每一行或几乎每一行。将这些操作瞬间完成是没有魔力的。
其次,您的WHERE source != ''
过滤器可能会破坏您的索引。您可以尝试使用WHERE source > ''
。这将允许MySQL的查询规划器随机访问您的索引,然后按顺序扫描它。
第三,您的子集source
索引(source(30)
)无助于提升效果。
第四,您可以尝试在这些列上创建覆盖索引的化合物:
ALTER TABLE dbname.sheet
ADD INDEX `reprting_module` (source, product_price, quantity);
然后像这样编写你的查询:
SELECT source, SUM(product_price*quantity) AS price
FROM sheet
WHERE source > ''
GROUP BY source
ORDER BY SUM(product_price*quantity) DESC
如果你很幸运,这会更快一些。为什么?因为MySQL可以通过随机访问索引到第一个非空source
值来满足整个查询,然后依次扫描索引来执行计算。
请注意,如果您使用
,我显示的查询,以及我显示的索引,确实非常快 WHERE source = 'some-particular-value'
缩小计算范围。
答案 1 :(得分:0)
"前缀"索引,例如INDEX(source(30))
,实际上是无用的。请提供SHOW CREATE TABLE
。如果source
可能是VARCHAR(255)
或更小,只需添加INDEX(source)
但这可能在此处没用,因为需要阅读大部分表格。
你有多少内存? innodb_buffer_pool_size
的价值是多少?桌子有多大(GB)?这些结合起来询问您是CPU绑定还是I / O绑定,以及简单的调整修复是否可以将其从I / O更改为CPU,从而可能将其加速到2秒。 (仅仅10万行,20秒似乎非常高。)