Re: col1 ILIKE 'foo%' not behaving the same as lower(col1) LIKE 'foo%'

From: milos d <acerbitdrain(at)hotmail(dot)com>
To: <pgsql-performance(at)postgresql(dot)org>
Subject: Re: col1 ILIKE 'foo%' not behaving the same as lower(col1) LIKE 'foo%'
Date: 2009-02-12 23:49:46
Message-ID: COL115-W82106E307A60E13B366D3AD5BB0@phx.gbl
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-performance


Thanks Scott,

Yes you are right, my code does lower case 'foo%'. I would expect SELECT ... WHERE col1 ILIKE 'foo%' to use an index.
The way I understand it is that the planner would translate this to SELECT ... WHERE lower(col1) LIKE lower('foo%') ?

You may be right, with more tests I see that ILIKE never uses an index. e.g SELECT ... WHERE lower(col1) ILIKE lower('foo%' ) doesn't use an index.

I think we need clarification from the developers.

Tools like Hibernate and NHibernate use ILIKE to do insensitive matching when using PostgresDialect.

Regards,
Milos.

From: scott(at)richrelevance(dot)com
To: dev(at)archonet(dot)com; acerbitdrain(at)hotmail(dot)com
CC: pgsql-performance(at)postgresql(dot)org
Date: Thu, 12 Feb 2009 11:50:42 -0800
Subject: Re: [PERFORM] col1 ILIKE 'foo%' not behaving the same as lower(col1) LIKE 'foo%'

Re: [PERFORM] col1 ILIKE 'foo%' not behaving the same as lower(col1) LIKE 'foo%'

I’m pretty sure the intent was:

WHERE lower(col1) LIKE lower(‘foo%’);

Most likely, his client code ensures the lower on the string passed in the query. Whether it should use an index or not has nothing to do with his example.

All I can do when answering this question, is confirm that the query planner doesn’t know when it can and can’t pair ILIKE with an index, even if lower() or upper() are used on parameters and indexes.

I use

WHERE lower(col1) LIKE

(and create a functional index on lower(col1))

And just pretend that there isn’t an ILIKE.

On 2/12/09 4:04 AM, "Richard Huxton" <dev(at)archonet(dot)com> wrote:

milos d wrote:

> Hello,

>

> I have a table 'foo_bar' with a column 'col1' defined as

> 'col1 varchar(512)'. This column is indexed using an expression index

> defined as

>

> CREATE INDEX ix_foo_bar_by_col1 ON foo_bar(lower(col1) col1 varchar_pattern_ops)

>

> The

> problem is when I try matching using ILIKE, (col1 ILIKE 'foo%')

> PostgreSQL does not use an index scan but a Seq scan of the whole

> table, but when I try (lower(col1) LIKE 'foo%')

> PostgreSQL uses an index scan.

Why should it use the index? They're not even equivalent queries:

SELECT ... WHERE lower(col1) LIKE 'FOO%'

SELECT ... WHERE col1 ILIKE 'FOO%'

One is guaranteed to return no rows, the other not.

--

Richard Huxton

Archonet Ltd

--

Sent via pgsql-performance mailing list (pgsql-performance(at)postgresql(dot)org)

To make changes to your subscription:

http://www.postgresql.org/mailpref/pgsql-performance

_________________________________________________________________
Need a new place to rent, share or buy? Let ninemsn property help
http://a.ninemsn.com.au/b.aspx?URL=http%3A%2F%2Fninemsn%2Edomain%2Ecom%2Eau%2F%3Fs%5Fcid%3DFDMedia%3ANineMSN%5FHotmail%5FTagline&_t=774152450&_r=Domain_tagline&_m=EXT

In response to

Browse pgsql-performance by date

  From Date Subject
Next Message Rusty Conover 2009-02-13 01:32:43 Re: GIST versus GIN indexes for intarrays
Previous Message Tom Lane 2009-02-12 21:29:38 Re: [PERFORM] GIST versus GIN indexes for intarrays