When using locales other than C
(ie POSIX
) you need to create your indexes for LIKE
and ~
prefix text searches using the text_pattern_ops
opclass. See the docs on Operator classes and index types. I'm sure there's a better reference than that docs page but I can't seem to find it at the moment.
If I alter your SQLFiddle to use text_pattern_ops
for the en_US
index you'll see that it's able to use the index:
create index tab_ix_foo on tab using btree (foo collate "en_US" text_pattern_ops);
-- ^^^^^^^^^^^^^^^^
It is quite likely that you'll need to create different indexes for different collations if you're using the COLLATE
option in 9.2+, since pretty much by definition different collations imply different orderings of strings and therefore different b-tree organisation. It appears that you are already doing this in your tests.
It's also possible that your data is just too small for index use to be particularly useful. Try testing with a more useful amount of data.
This post may be useful, as may the docs on Collation support.
For why you can't just use the same b-tree index for different collations, consider that b-trees require a stable and consistent ordering, but:
regress=> SELECT ' Bill''s' > ('bills' COLLATE "POSIX");
?column?
----------
f
(1 row)
regress=> SELECT ' Bill''s' > ('bills' COLLATE "en_US");
?column?
----------
t
(1 row)
As you can see, the collation changes the sort ordering. That's what a collation does, pretty much by definition. Trying to use the same index for different collations is like trying to use the same functional index for different functions; it makes absolutely no sense.