Plánovač dotazů PostgreSQL je chytrý, ale není AI. Chcete-li to provést, použijte index u výrazu použijte přesně stejnou formu vyjádření v dotazu.
S indexem, jako je tento:
CREATE INDEX t_a_lower_idx ON t (lower(substring(a, 1, 4)));
Nebo jednodušeji v PostgreSQL 9.1:
CREATE INDEX t_a_lower_idx ON t (lower(left(a, 4)));
Použijte tento dotaz:
SELECT * FROM t WHERE lower(left(a, 4)) = 'abcd';
Což je 100% funkčně ekvivalentní:
SELECT * FROM t WHERE lower(a) LIKE 'abcd%'
Nebo:
SELECT * FROM t WHERE a ILIKE 'abcd%'
Ale ne :
SELECT * FROM t WHERE a LIKE 'abcd%'
Toto je funkčně jiný dotaz a potřebujete jiný index:
CREATE INDEX t_a_idx ON t (substring(a, 1, 4));
Nebo jednodušší s PostgreSQL 9.1:
CREATE INDEX t_a_idx ON t (left(a, 4));
A použijte tento dotaz:
SELECT * FROM t WHERE left(a, 4) = 'abcd';
Hledané výrazy proměnné délky ukotvené vlevo
Nerozlišují se malá a velká písmena. Index:
Upravit :Skoro jsem zapomněl:Pokud spouštíte svou db s jakýmkoli jiným národním prostředím, než je výchozí 'C', musíte určete explicitně třídu operátoru
- text_pattern_ops
v mém příkladu:
CREATE INDEX t_a_lower_idx
ON t (lower(left(a, <insert_max_length>)) text_pattern_ops);
Dotaz:
SELECT * FROM t WHERE lower(left(a, <insert_max_length>)) ~~ 'abcdef%';
Může využívat index a je téměř stejně rychlý jako varianta s pevnou délkou.
Mohl by vás zajímat tento příspěvek na dba.SE s dalšími podrobnostmi o porovnávání vzorů
, zejména poslední část o operátorech ~>=~
a ~<~
.