mysql:对索引字段的慢查询

时间:2013-05-08 19:22:00

标签: mysql

orders表有2m记录。有大约900K的独特ship-to-id s。

ship_to_id上有一个索引(字段为int(8))。

以下查询需要近1000万才能完成。我已经PROCESSLIST运行了Command = QueryState = Sending Data

当我运行explain时,会使用现有索引,possible_keysNULL

我有什么办法可以加快查询速度吗?感谢。

SELECT 
  ship_to_id as customer_id 
FROM orders 
GROUP BY ship_to_id 
HAVING SUM( price_after_discount ) > 0

3 个答案:

答案 0 :(得分:4)

看起来你没有有用的索引。尝试在price_after_discount上添加索引,并添加如下所示的where条件:

WHERE price_after_discount > 0

最小化你需要求和的行数,因为你显然可以丢弃任何0。

同时尝试运行“top”命令,并在查询运行时查看io“wait”列。如果它很高,则意味着您的查询会导致大量磁盘I / O.如果你有RAM来加速它(如果你使用innodb)或myisam是通过文件系统缓存完成的,你可以增加各种内存缓冲区。重新启动服务器将刷新这些缓存。

如果你没有足够的RAM(对于2M记录你不需要太多),那么考虑一个分区方案,可能是对于post-to-id列(如果你的mysql版本支持它)。

答案 1 :(得分:2)

如果该表中的所有订单都不是最新的(即不会再次更改),那么您可以将它们存档到另一个表中以减少需要扫描的数据量。

另一种选择是使用索引在表上抛出last_modified时间戳。然后,您可以跟踪查询的运行时间并将结果存储在另一个表(query_results)中。当再次运行查询时,您只需要选择自上次运行查询以来修改过的订单,然后使用它来更新query_results。逻辑稍微复杂一点,但假设在查询执行之间更新了低百分比的订单,它应该快得多。

答案 2 :(得分:2)

MySQL 使用group by的索引,至少根据文档,here解释。

最有用的是,查询中使用的所有列都应该在索引中。这可以防止引擎引用原始数据和索引。因此,请尝试orders(ship_to_id, price_after_discount)上的索引。

相关问题