php—在查询中使用聚合函数时会花费大量时间

gev0vcfq  于 2021-06-24  发布在  Mysql
关注(0)|答案(2)|浏览(331)

表有100000条记录,使用聚合函数时需要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));

这是解释查询后的输出

uttx8gqw

uttx8gqw1#

“前缀”索引,例如 INDEX(source(30)) ,几乎毫无用处。请提供 SHOW CREATE TABLE . 如果 source 可以是 VARCHAR(255) 或更小,只需添加 INDEX(source) 但这在这里可能没有用,因为大多数表都需要读取。
你有多少公羊?它的价值是什么 innodb_buffer_pool_size ? 这个表有多大?这些问题结合起来询问您是cpu绑定还是i/o绑定,以及一个简单的调优修复程序是否可以将其从i/o更改为cpu,从而可能将其速度提高到2秒(对于10万排来说,20秒似乎非常高。)

lyr7nygr

lyr7nygr2#

首先,您要求您的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'

缩小计算范围。

相关问题