Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Optimization of search on concatenated firstname and lastname in PostgreSQL

I've written a SQL query in Postgres which search for a user by both firstname and lastname. My question is simply if it can be optimized, since it will be used a lot.

CREATE INDEX users_firstname_special_idx ON users(firstname text_pattern_ops);
CREATE INDEX users_lastname_special_idx ON users(lastname text_pattern_ops);

SELECT id, firstname, lastname FROM users WHERE firstname || ' ' || lastname ILIKE ('%' || 'sen' || '%') LIMIT 25;

If I run an explain I get the followin output:

Limit  (cost=0.00..1.05 rows=1 width=68)
  ->  Seq Scan on users  (cost=0.00..1.05 rows=1 width=68)
        Filter: (((firstname || ' '::text) || lastname) ~~* '%sen%'::text)

As I understand I should try and make postgrep skip the "Filter:"-thing. Is that correct?

Hope you guys have any suggestions.

Cheers.

like image 650
Cyberlurk Avatar asked Dec 19 '22 01:12

Cyberlurk


2 Answers

If you have more than 1 % wildcards in a string, you need to use a trigram index.

In your case, however, you are doing something odd. You concatenate firstname and lastname, with a space in the middle. The search string '%sen%' is therefore only present in the firstname or the lastname and never including the space. A better solution would therefore be:

CREATE INDEX users_firstname_special_idx ON users USING gist (firstname gist_trgm_ops);
CREATE INDEX users_lastname_special_idx ON users USING gist (lastname gist_trgm_ops);

SELECT id, firstname || ' ' || lastname AS fullname
FROM users
WHERE firstname ILIKE ('%sen%') OR lastname ILIKE ('%sen%')
LIMIT 25;
like image 179
Patrick Avatar answered Dec 21 '22 23:12

Patrick


You described situation exactly from PostgreSQL Documentation:

Indexes on Expressions

like image 41
sibnick Avatar answered Dec 21 '22 22:12

sibnick