In Postgres 9.6, on a users table with around 12 million rows, where the active boolean column has a btree index on it.
EXPLAIN ANALYZE SELECT * FROM users WHERE active = 'f' LIMIT 1;
Limit (cost=0.00..0.14 rows=1 width=982) (actual time=0.039..0.040 rows=1 loops=1)
-> Seq Scan on users (cost=0.00..3190979.68 rows=23264168 width=982) (actual time=0.036..0.036 rows=1 loops=1)
Filter: (NOT active)
Rows Removed by Filter: 115
Planning time: 0.161 ms
Execution time: 0.067 ms
But, using IS FALSE seems to use the index.
EXPLAIN ANALYZE SELECT * FROM users WHERE active IS FALSE LIMIT 1;
Limit (cost=0.44..0.59 rows=1 width=982) (actual time=0.054..0.056 rows=1 loops=1)
-> Index Scan using index_users_on_active on users (cost=0.44..2059.14 rows=13183 width=982) (actual time=0.051..0.051 rows=1 loops=1)
Index Cond: (active = false)
Filter: (active IS FALSE)
Planning time: 0.170 ms
Execution time: 0.094 ms
The vast majority of the records, the active value is true, and I understand an index isn't always faster.
It seems that Rails prefers the active = 'f' syntax, as that's what it outputs when you build a query.
Why are these different? How are they different? Should the other ever be used?
User.where(active: false).limit(1).to_sqlreturnsSELECT "users".* FROM "users" WHERE "users"."active" = 'f' LIMIT 1