You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
In case when an index is present, using `lower()` prevents from using
the index.
The index is typically present for columns with uniqueness, and
`lower()` is added for `validates_uniqueness_of ..., case_sensitive: false`.
However, if the index is defined with `lower()`, the query without
`lower()` wouldn't use the index either.
Setup:
```
CREATE EXTENSION citext;
CREATE TABLE citexts (cival citext);
INSERT INTO citexts (SELECT MD5(random()::text) FROM generate_series(1,1000000));
```
Without index:
```
EXPLAIN ANALYZE SELECT * from citexts WHERE cival = 'f00';
Gather (cost=1000.00..14542.43 rows=1 width=33) (actual time=165.923..169.065 rows=0 loops=1)
Workers Planned: 2
Workers Launched: 2
-> Parallel Seq Scan on citexts (cost=0.00..13542.33 rows=1 width=33) (actual time=158.218..158.218 rows=0 loops=3)
Filter: (cival = 'f00'::citext)
Rows Removed by Filter: 333333
Planning Time: 0.070 ms
Execution Time: 169.089 ms
Time: 169.466 ms
EXPLAIN ANALYZE SELECT * from citexts WHERE lower(cival) = lower('f00');
Gather (cost=1000.00..16084.00 rows=5000 width=33) (actual time=166.896..169.881 rows=0 loops=1)
Workers Planned: 2
Workers Launched: 2
-> Parallel Seq Scan on citexts (cost=0.00..14584.00 rows=2083 width=33) (actual time=157.348..157.349 rows=0 loops=3)
Filter: (lower((cival)::text) = 'f00'::text)
Rows Removed by Filter: 333333
Planning Time: 0.084 ms
Execution Time: 169.905 ms
Time: 170.338 ms
```
With index:
```
CREATE INDEX val_citexts ON citexts (cival);
EXPLAIN ANALYZE SELECT * from citexts WHERE cival = 'f00';
Index Only Scan using val_citexts on citexts (cost=0.42..4.44 rows=1 width=33) (actual time=0.051..0.052 rows=0 loops=1)
Index Cond: (cival = 'f00'::citext)
Heap Fetches: 0
Planning Time: 0.118 ms
Execution Time: 0.082 ms
Time: 0.616 ms
EXPLAIN ANALYZE SELECT * from citexts WHERE lower(cival) = lower('f00');
Gather (cost=1000.00..16084.00 rows=5000 width=33) (actual time=167.029..170.401 rows=0 loops=1)
Workers Planned: 2
Workers Launched: 2
-> Parallel Seq Scan on citexts (cost=0.00..14584.00 rows=2083 width=33) (actual time=157.180..157.181 rows=0 loops=3)
Filter: (lower((cival)::text) = 'f00'::text)
Rows Removed by Filter: 333333
Planning Time: 0.132 ms
Execution Time: 170.427 ms
Time: 170.946 ms
DROP INDEX val_citexts;
```
With an index with `lower()` has a reverse effect, a query with
`lower()` performs better:
```
CREATE INDEX val_citexts ON citexts (lower(cival));
EXPLAIN ANALYZE SELECT * from citexts WHERE cival = 'f00';
Gather (cost=1000.00..14542.43 rows=1 width=33) (actual time=174.138..177.311 rows=0 loops=1)
Workers Planned: 2
Workers Launched: 2
-> Parallel Seq Scan on citexts (cost=0.00..13542.33 rows=1 width=33) (actual time=165.983..165.984 rows=0 loops=3)
Filter: (cival = 'f00'::citext)
Rows Removed by Filter: 333333
Planning Time: 0.080 ms
Execution Time: 177.333 ms
Time: 177.701 ms
EXPLAIN ANALYZE SELECT * from citexts WHERE lower(cival) = lower('f00');
QUERY PLAN
----------------------------------------------------------------------------------------------------------------------------------
Bitmap Heap Scan on citexts (cost=187.18..7809.06 rows=5000 width=33) (actual time=0.021..0.022 rows=0 loops=1)
Recheck Cond: (lower((cival)::text) = 'f00'::text)
-> Bitmap Index Scan on lower_val_on_citexts (cost=0.00..185.93 rows=5000 width=0) (actual time=0.018..0.018 rows=0 loops=1)
Index Cond: (lower((cival)::text) = 'f00'::text)
Planning Time: 0.102 ms
Execution Time: 0.048 ms
(6 rows)
Time: 0.491 ms
```
0 commit comments