Operator "~<~" uses varchar_pattern_ops index while normal ORDER BY clause doesn't?
2
votes
1
answer
1370
views
Let's say I have a table with 1 000 000 records.
Structure of table is:
create table individual (
id serial primary key,
surname varchar(128),
"name" varchar(128),
patronymic varchar(128),
birth_dt date
)
I create a composite index.
#### INDEX 1
create index on individual using btree (upper(surname) varchar_pattern_ops
, upper("name") varchar_pattern_ops, patronymic varchar_pattern_ops, birth_dt);
Docs state that
varchar_pattern_ops
should be applied when using LIKE
or pattern match in query. Conclusion: this index will not be used in query below, even it gets only 10 row from 1 000 000.
#### QUERY 1
select * from individual
order by upper(surname), upper("name"), upper(patronymic), birth_dt limit 10;
and even more, docs recommends to create an index without varchar_pattern_ops
as well.
#### INDEX 2
create index on individual using btree
(upper(surname), upper("name"), upper(patronimyc), birth_dt);
Then a query using LIMIT
will use this index.
I found a cheat to force Postgres to use first index on Postgres users forum. It is operator ~<~
.
#### QUERY 2
select * from individual
order by upper(surname) using ~<~
, upper("name") using ~<~
, upper(patronymic) using ~<~
, birth_dt limit 100;
In this case **INDEX 1** will be used even if **INDEX 2** doesn't exists. I tried to investigate to discover why it happens, but failed.
There are some system tables like pg_operator
, which (I think) link operator ~<~
to some functions that most probably uses LIKE
or regular expressions.
I ran **QUERY 1** and **QUERY 2** a few times and compared result manually. It looks like operator ~<~
gives correct result, but I didn't risk anything and just create a normal index anyway.
I am still interested how the Postgres planner decides which index to use index where it meets the operator ~<~
in **QUERY 1**.
Asked by simar
(203 rep)
Mar 10, 2015, 10:57 AM
Last activity: Aug 1, 2023, 05:08 PM
Last activity: Aug 1, 2023, 05:08 PM