Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Performance differences between .exists? and .where.present?

What performance differences, if any, exist between the following two options (mentioned in this answer)

Thing.where(name: "Bob").present?

which produces the SQL

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

and

Thing.exists?(name: "Bob")

which produces the SQL

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

As the SQL statements are different, it's theoretically possible for differences in performance to exist. But I don't know whether, assuming name is indexed in the database, there's any practical difference. Also, is there any difference with regards to the amount of work being done in Ruby-land (such as initialization and GC).

If it makes any difference, I'm using Rails 3.2.20.

like image 869
Andrew Grimm Avatar asked Mar 15 '23 22:03

Andrew Grimm


1 Answers

You can do the benchmark by yourself like this:

$ 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 is indexed by database. If I choose a column which is not indexed, the result look like this:

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

There are about 30000 records for this table. So present? is slower than exist? because it has to count all matched records first.

like image 156
Yen-Ju Avatar answered Mar 31 '23 19:03

Yen-Ju