Sample Header Ad - 728x90

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