Postgres 9.6では、約1200万行のユーザーテーブルに、active
ブール列にbtreeインデックスが付いています。Postgresとインデックスの使用では、FALSEと= 'f'の差があります。
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
ただし、IS FALSE
を使用しているようです。
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
レコードの大半は、アクティブな値はtrue
ある、と私はインデックスが常に速くないです理解しています。
Railsは、active = 'f'
の構文を好んでいると思われます。これは、クエリをビルドするときに出力されるためです。
なぜこれらは異なるのですか?それらはどう違いますか?もう片方を使うべきか?
はRailsが好むものに詳しく説明してくださいインデックス条件ヒット(
Index Cond: (active = false)
)によるものであった:比較null = false
はnullを返しますという事実にもかかわらず、それは、結果セットには影響しません。 –'user.where(アクティブ:false).limit(1).to_sql'は ' SELECT "users"を返します。* "FROM" users "WHERE" users ""アクティブ "= 'f' LIMIT 1' – tibbon