【发布时间】:2010-02-01 16:55:06
【问题描述】:
我正在对 MySQL 数据库执行“从 bar 中选择 sum(foo)”查询,该数据库汇总了 7.3 毫米的记录,每次运行大约需要 22 秒。有没有加快 MySQL 求和的技巧?
【问题讨论】:
标签: mysql performance optimization sum
我正在对 MySQL 数据库执行“从 bar 中选择 sum(foo)”查询,该数据库汇总了 7.3 毫米的记录,每次运行大约需要 22 秒。有没有加快 MySQL 求和的技巧?
【问题讨论】:
标签: mysql performance optimization sum
不,你不能加速函数本身。这里的问题实际上是您选择了 730 万条记录。 MySQL 必须扫描整个表,而 730 万是一个相当大的数字。实际上,它完成得如此之快让我印象深刻。
您可以采用的策略是将数据分解为更小的子集(可能按日期?月份?),并为不会改变的旧数据保持一个总和。您可以定期更新总和,并且可以通过将总和以及此后添加的任何新数据相加来计算总体值,这将是更少的行数。
【讨论】:
在mysql中开启QUERY CACHE。默认情况下缓存是关闭的。你需要设置mysql ini文件。
-- hint mysql server about caching
SELECT SQL_CACHE sum(foo) FROM bar;
如果未对表进行任何更改,MySQL 优化器可能能够返回缓存。
在这里阅读更多: http://www.mysqlperformanceblog.com/2006/07/27/mysql-query-cache/
【讨论】:
foo 的值更新时,缓存值会更新吗?或者 MySQL 是否会在下次运行此查询时再次重新汇总整个表?
这里有两件事:
1) 您不应该定期对 730 万条记录进行求和 - 引入满足业务需求(按日、月、年、部门等)的临时表并按计划填充它们,可能会重复使用这些表而不是原始的“原始”表(例如在需要几天间隔时为每天选择汇总值等)
2) 检查您的交易设置
http://dev.mysql.com/doc/refman/5.0/en/set-transaction.html#isolevel_repeatable-read
【讨论】:
不,不是真的。它总是需要枚举表中的所有行。
您可以创建一个附加表并在每次插入、更新、删除时更新其中的总和?
【讨论】:
您或许可以尝试在 bar.foo 字段上添加索引。该索引将包含 bar 列的所有值,但比原始 foo 表更小,因此扫描速度更快,尤其是当 foo 有很多其他列时。
【讨论】:
如果您的查询真的那么简单,不... 但是,如果您使用的是更复杂的查询(并在此处缩写),您可以(可能) - 喜欢使用更好的连接...
【讨论】: