Rails在pgAdmin中查询缓慢但快速



我正试图弄清楚为什么我的rails应用程序中的一个查询执行得相当差。我使用的是Postgres9.3,rails 4.0.3和jRuby 1.7.10,所以这可能是JDBC驱动程序的问题?

但基本上,这是一个非常简单的查询:

SELECT * FROM table;

该表包含851行,所以它几乎不是一个庞大的数据集,所以我期待一个快速查询。当我在pgAdmin3中执行这个查询时,我得到了我所期望的:所有行都在15到35ms之间返回。漂亮又快!

然而,从铁轨上看,情况就不同了。在rails控制台中运行查询,我所能达到的最快速度是189ms,而通常在200ms左右。此查询通过调用Table.all运行

我最初的想法只是ActiveRecord在851对象的实例化中增加了开销,所以这显然会减慢它的速度。为了测试这一点,我运行了

ActiveRecord::Base.connection.execute("SELECT * FROM table")

虽然速度略有加快,但几乎所有的查询都是围绕150ms进行的,距离pgAdmin标记还有很长的路要走。作为最后一次尝试,我尝试了

ActiveRecord::Base.connection.exec_query_raw("SELECT * FROM table")

但这丝毫没有改善性能。

我现在真的很困惑,为什么速度慢得多,因为我看到pgAdmin和Rails之间的性能下降了10倍。在Rails中只执行了原始SQL之后,我知道它并不是ActiveRecord减缓了速度,所以我现在真的很困惑什么是

有人知道为什么这比应该的要慢得多吗?

更新

我做了更多的挖掘,这似乎是rails处理Date字段的方式。如果我手动选择表中的所有列,速度也一样慢,但如果我选择了除updated_atcreated_at之外的全部列,查询运行时间大约为2-4ms,这是完美的!

我现在唯一的问题是,如何绕过这个问题。有没有一种方法可以解决rails的日期性能问题,或者让rails不将其解析为日期并将其保存为字符串或类似内容?

更新2

因此,在进行了更多的挖掘并@stonehz向我指出了这篇文章中提出的错误之后,我已经升级到了Jruby 1.7.12rails 4.1.0,并注意到了相当大的速度。它与pgAdmin的性能相差不大,但我认为如果不完全删除日期列,我就不会有更好的结果。下面是我现在获得的基准

SELECT *:                        4.080000   0.330000   4.410000 (  5.243000)
SELECT date_fields:              1.960000   0.020000   1.980000 (  2.032000)
SELECT * - date_fields:          3.070000   0.070000   3.140000 (  3.247000)
--------------------------------------------------------- total: 9.530000sec
user     system      total        real
SELECT *:                        3.700000   0.060000   3.760000 (  4.663000)
SELECT date_fields:              1.790000   0.020000   1.810000 (  2.021000)
SELECT * - date_fields:          2.330000   0.060000   2.390000 (  3.180000)

此基准测试正在查询851行。第一个测试是一个简单的SELECT *语句。第二个测试只选择日期字段,最后一个测试选择日期字段以外的所有字段。每个查询运行100次以获得最终结果。

如图所示,select *语句现在只需要大约4秒就可以运行100次,因此每个查询只需要40ms,这更接近于大约30ms的pgAdmin时间。好多了!

他们已经解决了这个问题,并围绕您发现的错误打开了几张罚单:

https://github.com/jruby/jruby/issues/1662

https://github.com/jruby/activerecord-jdbc-adapter/issues/540

使用Jruby 1.7.12将使性能提高约5倍(正如他们的基准测试所暗示的那样)

我现在真的很困惑,因为我看到pgAdmin和Rails之间的性能下降了10倍。在Rails中只执行了原始SQL之后,我知道它并不是ActiveRecord减缓了速度,所以我现在真的很困惑什么是

它不像您的查询那样是ActiveRecord。

当你在pg admin中运行这个查询时,据我所知,它实际上并没有运行它。PgAdmin对你的使用做了一些假设,即你最终会得到一个巨大的集合。从性能的角度来看,使用光标更有趣,这样可以根据需要通过获取行而不是一次获取行来导航庞大的集合。我想这正是正在发生的事情。

相反,当你在应用程序中运行相同的查询时,你要负责做这种事情。或者就这一点而言,一开始就不运行这种查询。需要从数据库表中选择所有行通常表明应用程序的设计有问题。

最新更新