使用活动记录的区别是什么?与find_by ?

时间:2021-08-23 13:23:07

In my model, I check if a Sudoku record exists in the database first before I either fetch it's solution or create it.

在我的模型中,我首先检查数据库中是否存在一个数独记录,然后取回它的解决方案或创建它。

if Sudoku.exists?(puzzle: puzzle)
  return Sudoku.find_by(puzzle: puzzle).solution
else
  **solve it and save it into the db**
end

What is the difference from doing this:

这样做的区别是什么:

if Sudoku.find_by(puzzle: puzzle)
  return Sudoku.find_by(puzzle: puzzle).solution
else
  **solve it and save it into the db**
end

Logs for exists?

日志存在吗?

Sudoku Exists (0.0ms)  SELECT  1 AS one FROM "sudokus" WHERE "sudokus"."puzzle" = $1 LIMIT 1  [["puzzle", "390820700801500069020160403002096058935000602060752030703941000200037590019000347"]]
  Sudoku Load (0.0ms)  SELECT  "sudokus".* FROM "sudokus" WHERE "sudokus"."puzzle" = $1 LIMIT 1  [["puzzle", "390820700801500069020160403002096058935000602060752030703941000200037590019000347"]]
Completed 200 OK in 8ms (Views: 0.2ms | ActiveRecord: 3.0ms)

Logs for find_by

日志find_by

 Sudoku Load (0.0ms)  SELECT  "sudokus".* FROM "sudokus" WHERE "sudokus"."puzzle" = $1 LIMIT 1  [["puzzle", "390820700801500069020160403002096058935000602060752030703941000200037590019000347"]]
  CACHE (0.0ms)  SELECT  "sudokus".* FROM "sudokus" WHERE "sudokus"."puzzle" = $1 LIMIT 1  [["puzzle", "390820700801500069020160403002096058935000602060752030703941000200037590019000347"]]
Completed 200 OK in 7ms (Views: 0.2ms | ActiveRecord: 2.0ms)

At first, I thought by doing two find_by it would hit the database twice, but then I see the CACHE. Does that mean Rails remember the previous query in the first find_by and is only hitting it once?

一开始,我认为通过执行两个find_by,它会攻击数据库两次,但是之后我看到了缓存。这是否意味着Rails记住了第一个find_by中的前一个查询,并且只命中它一次?

Why would I use exists? over find_by ?

我为什么要使用存在?find_by ?

Edit:

编辑:

From advice, I'm using this now:

根据建议,我现在正在使用这个:

if sudoku = Sudoku.find_by(puzzle: puzzle)
  return sudoku.solution
else
  **solve it and save it into the db**
end

1 个解决方案

#1


4  

Rails wraps each controller action with a simple query cache. The CACHE in the logs does indicates that the query was served from the cache. If you were to run that code in the console you wouldn't get that caching (unless you explicitly set that up).

Rails用一个简单的查询缓存来包装每个控制器操作。日志中的缓存确实表明查询是由缓存提供的。如果您要在控制台中运行该代码,就不会获得缓存(除非您显式地设置它)。

The difference query wise is that none of the fields of the object are fetched from the database. Aside from the network impact, depending on the query and the indices present, your database may be able to use a covering index (in a nutshell the index can be used to answer the query completely instead of the db using the index to find the data for the row)

不同的查询是,对象的任何字段都不会从数据库中获取。除了网络影响之外,取决于查询和索引的存在,您的数据库可能能够使用覆盖索引(简单地说,索引可以用来完全地回答查询,而不是使用索引查找行中的数据)

On top of that rails doesn't construct an active record object from the result, you just get back true/false.

在rails没有从结果构造活动记录对象的基础上,您只需返回true/false。

So exists? is faster. However it's pointless if you then call find_by straight after. You might as well call find_by once only.

所以存在吗?更快。但是,如果您然后直接调用find_by,这是没有意义的。您不妨只调用find_by一次。

#1


4  

Rails wraps each controller action with a simple query cache. The CACHE in the logs does indicates that the query was served from the cache. If you were to run that code in the console you wouldn't get that caching (unless you explicitly set that up).

Rails用一个简单的查询缓存来包装每个控制器操作。日志中的缓存确实表明查询是由缓存提供的。如果您要在控制台中运行该代码,就不会获得缓存(除非您显式地设置它)。

The difference query wise is that none of the fields of the object are fetched from the database. Aside from the network impact, depending on the query and the indices present, your database may be able to use a covering index (in a nutshell the index can be used to answer the query completely instead of the db using the index to find the data for the row)

不同的查询是,对象的任何字段都不会从数据库中获取。除了网络影响之外,取决于查询和索引的存在,您的数据库可能能够使用覆盖索引(简单地说,索引可以用来完全地回答查询,而不是使用索引查找行中的数据)

On top of that rails doesn't construct an active record object from the result, you just get back true/false.

在rails没有从结果构造活动记录对象的基础上,您只需返回true/false。

So exists? is faster. However it's pointless if you then call find_by straight after. You might as well call find_by once only.

所以存在吗?更快。但是,如果您然后直接调用find_by,这是没有意义的。您不妨只调用find_by一次。