0

I have a usernames table with a username string field, I have a "start with" query and trying both pattern and regex matching

SELECT username FROM usernames WHERE username LIKE 'foo%';
SELECT username FROM usernames WHERE username ~ '^foo';

I have a b-tree index on the username field and SET ENABLE_SEQSCAN =false; , When I EXPLAIN the abovementioned queries, the query planner uses SEQ_SCAN (Seq Scan)

I am using PostgreSQL 13.4 , tried VACUUM (VERBOSE, ANALYZE) usernames and REINDEX TABLE usernames too

What's wrong here?

3
  • 2
    Please show the index definition and your locale. My guess is that your locale is not c and the index was not defined with text_pattern_ops: postgresql.org/docs/current/indexes-opclass.html Commented Sep 26, 2021 at 11:23
  • LC_COLLATE and LC_CTYPE both are fa_IR Commented Sep 26, 2021 at 12:56
  • @Jeremy Thanks a lot, you are right, text_pattern_ops solved the problem :-) Commented Sep 26, 2021 at 13:06

3 Answers 3

2

The best index for the LIKE query would be

CREATE INDEX ON usernames (username text_pattern_ops);

For the regular expression match, you would need a trigram index, but it is easier to use the LIKE version instead.

Sign up to request clarification or add additional context in comments.

2 Comments

As I have already a b-tree index on username field and my query is start with query, the b-tee index is appropriate and I don't want to add overload to database for a redundant index
Drop the other index. The index I suggest works just as well for equality searches. Only to support inequality conditions (<, <=, > and >=) or ORDER BY you need a normal B-tree index.
0

Ideally by default once the B-tree index has been created it should be using the Index Scan, the only condition otherwise is-

using the LIKE keyword followed by a wildcard and then a string ('%nik') cannot use an index defined on the column but if it is vice versa then the index is used ('Slo%')

Try passing hints to the Query plan builder, also is Index_scan enabled?

/*+IndexScan(username)*/ select username from usernames where username like 'foo%'

5 Comments

I asked that my query is START WITH, not END WITH
SHOW enable_indexscan is on
AFAIK there is no index hint in PostgreSQL ,how to hint?
refer this link
That's an extension, there's no reason to believe the op has it installed.
0

This is happening because of 'where' condition given in the statement (username LIKE 'foo%'). Here You are trying to fetch all rows which meet this pattern. Therefore it required to check all rows which is started with character "foo" and ignore the index.

4 Comments

According to documentation The optimizer can also use a B-tree index for queries involving the pattern matching operators LIKE and ~ if the pattern is a constant and is anchored to the beginning of the string — for example, col LIKE 'foo%' or col ~ '^foo', but not col LIKE '%bar'.
What percentage of rows return by these queries?
A few, less than 1%
Consider that I am using SET ENABLE_SEQSCAN =false;

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.