Het is net zoals je elders uit jjanes leest:een expressie-index wordt alleen in overweging genomen als de expressie exact overeenkomt in het query-predikaat. De queryplanner van Postgres is geen AI. Het zou snel voorbijgaan aan het doel van snelle zoekopdrachten als het plannen ervan te lang duurt.
Je kunt je index een beetje optimaliseren, als dat een troost is. left()
is eenvoudiger en sneller dan substring()
:
CREATE INDEX record_changes_log_detail_old_value_ix_btree
ON record_changes_log_detail (left(old_value,1024) text_pattern_ops);
Er is ook een maximale rijgrootte van 2704 bytes voor btree-indexen, geen "limiet van 2172 tekens op B-trees" .
Het belangrijkste is dat voor alleen gelijkheidscontroles, zoals uw vraag suggereert, een btree-index op een hash-waarde met behulp van md5(old_value)
of hashtext(old_value)
zou veel zijn efficiënter. Als je dat doet, denk er dan aan om je te verdedigen tegen hashbotsingen zoals zo:
SELECT *
FROM record_changes_log_detail
WHERE hashtext(old_value) = hashtext('Gold Kerrison Neuro')
AND old_value = 'Gold Kerrison Neuro';
Het eerste predikaat geeft u snelle indextoegang. De tweede sluit valse positieven uit. Aanrijdingen zouden uiterst zeldzaam moeten zijn. Maar mogelijk. En de mogelijkheid groeit met de grootte van de tafel.
Gerelateerd:
- SELECT-query met DISTINCT op een tabelstructuur voor grafieken is erg traag
- Wat is het optimale gegevenstype voor een MD5-veld?
- Zoeken in volledige tekst in CouchDB
Of een hash-index zoals je zelf al hebt overwogen:
- Waarom is een Postgres 11 hash-index zo groot?
(Hier hoeft u zich geen zorgen te maken over hash-botsingen; ze worden intern afgehandeld.)