Prior to Rails 5.2, MySQL and PostgreSQL adapters had select_value , select_values & select_rows select_{value,values,rows} methods. They improve the performance by not instantiating ActiveRecord::Result .

However these methods broke query caching of ActiveRecord::FinderMethods#exists? method. Let’s check the issue.

>> User . cache do >> 2 . times { User . exists? ( 1 ) } >> end User Exists ( 2.1 ms ) SELECT 1 AS one FROM "users" WHERE "users" . "id" = $1 LIMIT $2 [[ "id" , 1 ], [ "LIMIT" , 1 ]] User Exists ( 2 ms ) SELECT 1 AS one FROM "users" WHERE "users" . "id" = $1 LIMIT $2 [[ "id" , 1 ], [ "LIMIT" , 1 ]]

As we can see, query was not cached and sql was executed second time.

From Rails 5.2, MySQL and PostgreSQL adapters are no longer override select_{value,values,rows} methods which fix this query caching issue.

Also, the performance improvement provided by these methods was marginal and not a hotspot in Active Record, so this change was accepted.

Let’s check query caching of ActiveRecord::FinderMethods#exists? after the change.

>> User . cache do >> 2 . times { User . exists? ( 1 ) } >> end User Exists ( 2.1 ms ) SELECT 1 AS one FROM "users" WHERE "users" . "id" = $1 LIMIT $2 [[ "id" , 1 ], [ "LIMIT" , 1 ]] CACHE User Exists ( 0.0 ms ) SELECT 1 AS one FROM "users" WHERE "users" . "id" = $1 LIMIT $2 [[ "id" , 1 ], [ "LIMIT" , 1 ]]

Now, query has been cached as expected.

This change has been backported in rails 5.1 from version 5.1.2 as well.