Quick PostgreSQL optimization story

11 March 2006   1 comment   Work

Mind That Age!

This blog post is 11 years old! Most likely, its content is outdated. Especially if it's technical.

Powered by Fusion×

There are several ways to do case insensitive string matching in SQL. Here are two ways that I've tried and analyzed on a table that doesn't have any indices.

Option 1:

(
 LOWER(u.first_name) = LOWER('Lazy') OR 
 LOWER(u.last_name) = LOWER('Lazy') OR
 LOWER(u.first_name || u.last_name) = LOWER('Lazy')
)

Option 2:

(
 u.first_name ILIKE 'Lazy' OR 
 u.last_name ILIKE 'Lazy' OR
 u.first_name || u.last_name ILIKE 'Lazy'
)

A potentially third option is to make sure that the parameters sent to the SQL code is cooked, in this case we make the parameter into lower case before sent to the SQL code

Option 1b:

(
 LOWER(u.first_name) = 'lazy' OR 
 LOWER(u.last_name) = 'lazy' OR
 LOWER(u.first_name || u.last_name) = 'lazy'
)

Which one do you think is fastest?

The results are:

Option 1:  2.0ms - 2.5ms (average 2.25ms)
Option 1b: 2.0ms - 2.1ms (average 2.05ms)
Option 2: 1.7ms - 2.0ms (average 1.85ms)

Conclusion: the ILIKE operator method is the fastest. Not only is it faster, it also supports regular expressions.

I've always thought that the LIKE and ILIKE were sinfully slow (yet useful when time isn't an issue). I should perhaps redo these tests with an index on the first_name and last_name columns.

Comments

djo
Try

CREATE INDEX u_first_name_index ON u (lower(first_name));

or a variation thereof.

(Ah, I just noticed you wrote "without any indices". You probably already know this, then. I'll post it anyway - for the search engines.)

You could also use a shadow column maintained by a trigger, but that's an evil solution, only to be used in almost never-met circumstances.
Thank you for posting a comment

Your email will never ever be published


Related posts

Previous:
Squeezebox + Pandora 08 March 2006
Next:
Carbon XEmacs installed 14 March 2006
Related by Keyword:
Fastest way to match a filename's extension in Python 31 August 2017
Don't forget your sets in Python! 10 March 2017
Optimization of QuerySet.get() with or without select_related 03 November 2016
How to no-mincss links with django-pipeline 03 February 2016
mozjpeg installation and sample 10 October 2015
Related by Text:
Fastest *local* cache backend possible for Django 04 August 2017
UPPER vs. ILIKE 19 April 2010
Optimization of QuerySet.get() with or without select_related 03 November 2016
How much faster is Nginx+gunicorn than Apache+mod_wsgi? 22 March 2012
Simple or fancy UPSERT in PostgreSQL with Django 11 October 2017