Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails 如何加速简单的rails数据库查询?_Ruby On Rails_Ruby_Ruby On Rails 4 - Fatal编程技术网

Ruby on rails 如何加速简单的rails数据库查询?

Ruby on rails 如何加速简单的rails数据库查询?,ruby-on-rails,ruby,ruby-on-rails-4,Ruby On Rails,Ruby,Ruby On Rails 4,我正在ruby 2.6.3上使用rails 4.2.11.1 使用rails时,我的请求速度非常慢,因此我对代码进行了基准测试,找到了罪魁祸首。大多数减速发生在数据库调用中,我从数据库中的表中选择一行。我尝试过同一想法的几种不同版本 使用此版本 Rails.logger.info Benchmark.measure{ result = Record.find_by_sql(['SELECT column FROM table WHERE condition']).first.column }

我正在ruby 2.6.3上使用rails 4.2.11.1

使用rails时,我的请求速度非常慢,因此我对代码进行了基准测试,找到了罪魁祸首。大多数减速发生在数据库调用中,我从数据库中的表中选择一行。我尝试过同一想法的几种不同版本

使用此版本

Rails.logger.info Benchmark.measure{
  result = Record.find_by_sql(['SELECT column FROM table WHERE condition']).first.column
}
rails输出表示sql需要54.5ms,但基准测试输出0.043427 0.006294 0.049721 1.795859,总请求需要1.81秒。当我直接在postgres终端上运行上述sql时,需要42毫秒

显然,问题不在于我的sql太慢。42毫秒不明显。但是1.79秒的速度太慢了,会造成糟糕的用户体验

我读了一些书,得出了这样的结论:速度减慢是由rails的对象创建造成的,这看起来很奇怪,但显然速度可能会非常慢,所以我尝试使用Pulk来尽量减少创建的对象数量:

Rails.logger.info Benchmark.measure{
    result = Record.where(condition).pluck(column).first
}
现在rails说sql需要29.3ms,而基准测试给出了0.017989 0.006119 0.024108 0.713973 整个请求需要0.731秒。这是一个巨大的改进,但是0.7秒仍然是一个严重的减速,并且仍然破坏了我的应用程序的可用性


我做错了什么?对我来说,这么简单的事情竟然会有如此巨大的减速,这似乎太疯狂了。如果rails就是这样工作的,我无法想象会有人将其用于严肃的应用程序

正如我前面提到的,我不知道如果你只想要第一个,为什么要要求所有的匹配

如果我这样做:

 Rails.logger.info Benchmark.measure{
   result = User.where(email: 'foo@bar.com').pluck(:email).first 
 }

(9.6ms)  SELECT "users"."email" FROM "users" WHERE "users"."email" = $1  [["email", "foo@bar.com"]]
#<Benchmark::Tms:0x00007fc2ce4b7998 @label="", @real=0.6364280000561848,     @cstime=0.00364, @cutime=0.000661, @stime=0.1469640000000001, @utime=0.1646029999999996, @total=0.3158679999999997>

 Rails.logger.info Benchmark.measure{
   result = User.where(email: 'foo@bar.com').limit(1).pluck(:email) 
 }

 (1.8ms)  SELECT  "users"."email" FROM "users" WHERE "users"."email" = $1 LIMIT $2  [["email", "foo@bar.com.com"], ["LIMIT", 1]]
#<Benchmark::Tms:0x00007fc2ce4cd838 @label="", @real=0.004004000045824796, @cstime=0.0, @cutime=0.0, @stime=0.0005539999999997214, @utime=0.0013550000000002171, @total=0.0019089999999999385>
Rails也提供现金服务。如果再次运行查询,第二次应该会更快。你的where条件有多复杂?这可能是它的一部分。

find\u by\u sql对数据库执行自定义sql查询并返回所有结果

这意味着将返回并实例化数据库中的所有记录。只有这样,才能通过调用结果的first从该数组中选择第一个

当您第一次调用ActiveRecord::Relation时,它将为您的查询添加一个限制,并仅选择您想要的行为

这意味着您应该自己限制查询:

结果=记录。通过_sql['SELECT column FROM table WHERE condition LIMIT 1']查找_。first.column
我敢肯定,您的请求会很快,因为ruby不需要实例化所有结果行。

很难从您呈现请求的一般方式中分辨出来。行中有多少列?创建的对象是否异常大?如果只需要第一个对象,为什么要使用where?您要求它搜索整个数据库中的匹配项,并返回所有匹配项,然后给出第一个匹配项。@Beartech该表似乎有大约50列。我不认为那是超大的。Rails为我准确地输出了它运行的sql语句,而对于第二个语句,它确实从table WHERE Condition中选择了table.column,所以它不会全部返回它们。它会在sql级别自动过滤掉它们。那么,你在哪个系统上运行整个应用程序呢?我在我6岁的笔记本电脑上开发,如果我推动它,rails可能会减慢速度,但它在Heroku上的生产中会飞起来。这是您的生产服务器吗?您将其与什么进行比较?where条件是对列的简单相等性检查,where column=选项,并且它是唯一的列。因此,此查询应始终返回一行。我尝试按照您的建议使用limit1,似乎平均需要约1秒。您使用的数据库是什么?我使用的是数据库中索引的列postgresIs?我会按id ASC添加顺序,以获得更可预测的结果。每行的条件都是唯一的,所以它无论如何只会返回一条记录。我刚刚用内置的limit 1进行了尝试,但仍然是1.7秒。有勇气的版本快得多