.exists? 和 .where.present? 之间的性能差异

4
如果存在的话,以下两个选项(在此答案中提到)之间是否存在性能差异?
Thing.where(name: "Bob").present?

生成SQL的代码

SELECT COUNT(*) FROM things WHERE things.name = "Bob";

并且

Thing.exists?(name: "Bob")

这会生成SQL语句。

SELECT 1 AS one from things WHERE name ="Bob" limit 1;

由于SQL语句不同,理论上性能差异是可能存在的。但是如果假设数据库中已经为“name”创建了索引,是否存在实际差异我就不清楚了。同时,Ruby代码中执行的工作量(如初始化和GC)是否有所不同也不确定。
如果有影响的话,我使用的是Rails 3.2.20版本。
1个回答

8
您可以像这样自己进行基准测试:
$ bin/rails c
> ids = Item::Project.pluck(:id)
> b = Benchmark.bmbm do |x|
>   x.report("present?") { 10000.times { Item::Project.where(id: ids.sample).present? } }
>   x.report("exist?") { 10000.times { Item::Project.exists?(id: ids.sample) } }
> end
> puts b
  4.650000   0.270000   4.920000 (  7.627897)
  4.660000   0.330000   4.990000 (  7.337031)

id是由数据库索引的。如果我选择一个没有被索引的列,结果会像这样:

  12.590000   0.740000  13.330000 ( 71.199677)
   8.350000   0.620000   8.970000 ( 34.846301)

这个表大约有30000条记录。因此,present?exist?慢,因为它必须先计算所有匹配的记录。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接