【发布时间】:2011-06-27 14:44:08
【问题描述】:
我有一个查询在 MySQL 控制台中运行非常快,但在我使用 Rails Active Record 运行时却非常慢。这是针对包含 700 万条记录的表运行的查询:
select broker_id,count(abserror),avg(abserror) from fc_estimates where (fpe > '2000-05-28') and (fpe group by broker_id order by broker_id;
运行需要 3 分钟。
然后我在 Rails Active Record 中运行这个查询:
统计 = 估计。 选择([ "broker_id", "count(abserror) as abserror_count", “avg(abserror) as abserror_avg” ])。 哪里( :fpe => ((fpe-1098).to_date..(fpe+30).to_date)) 组(“broker_id”)。 订单("broker_id")
生成这个 sql(从 to_sql 输出)
SELECT broker_id, count(abserror) as abserror_count, avg(abserror) as abserror_avg FROM fc_estimates WHERE (fc_estimates. fpe BETWEEN '2000-05-28' AND '2003-06-30') GROUP BY broker_id ORDER BY broker_id
运行需要 1 小时 40 分钟。它返回 250 条记录。
我正在使用 Windows 7、MySQl 5.1、Ruby 1.8.7、ActiveRecord 3.04、mysql2 gem 0.2.6
这些是 InnoDB 表,我已将 innodb_buffer_pool_size 增加到 480M(这确实有助于其他查询)。我观察到的一件事是 MySQL 内存使用量增加到大约 500M,然后有很多磁盘活动(页面交换)。这确实解释了一些事情。
但是,当在 MySQL 控制台中运行相同的查询只需要 3 分钟时,为什么我的性能如此糟糕?感谢您提出任何想法或遇到类似情况的任何人。
2011 年 2 月 24 日更新
我更新到 MySQL 5.5。现在我在控制台中的查询运行大约 1 分 40 秒。使用 ActiveRecords 大约需要 40 分钟。
【问题讨论】:
-
您可能会看到 mysql 查询缓存的结果。尝试在 mysql 中再次计时查询,但将 SQL_NO_CACHE 放在 SELECT 之后以禁用查询缓存。
-
是的,我想我明白了。我第二次在控制台中运行查询时,它运行得非常快。所以我的查询在 3 分钟内运行 - 第二次运行速度非常快。我不认为是这样,但我会检查。
-
针对如此少的行数 3 分钟有点令人担忧 - 如果您利用 innodb 聚集索引,您可能会获得不到 1 秒的运行时间。
-
刚刚再次运行查询。在 MySQL 控制台中,查询需要 4 分钟,再次运行需要 1 分钟 14 秒,再次运行需要 3 秒,再次运行需要 3 秒。所以我猜这是查询缓存生效。然后我使用 SELECT SQL_NO_CACHE ... 运行,查询耗时 2 分钟,再次使用 SELEC SQL_NO_CACHE,查询耗时 3 分 30 秒。实际上我的问题是磁盘被颠簸(有很多写入到 c:\pagefile.sys)。但为什么会这样呢?
-
3 分钟对我来说没问题 - 这不是一个 Web 应用程序。当我使用 ActiveRecord 时,1 小时 40 分钟很痛苦。
标签: mysql ruby-on-rails performance activerecord