Det er ligesom du læser fra jjanes andre steder:et udtryksindeks tages kun i betragtning, hvis udtrykket matches nøjagtigt i forespørgselsprædikatet. Postgres-forespørgselsplanlæggeren er ikke en AI. Det ville hurtigt besejre formålet med at lave forespørgsler hurtigt, hvis planlægningen af dem tager for lang tid.
Du kan optimere dit indeks lidt, hvis det er nogen trøst. left()
er enklere og hurtigere end substring()
:
CREATE INDEX record_changes_log_detail_old_value_ix_btree
ON record_changes_log_detail (left(old_value,1024) text_pattern_ops);
Der er også en maksimal rækkestørrelse på 2704 bytes for btree-indekser, ikke en "2172 tegnbegrænsning på B-træer" .
Vigtigst af alt er det kun for lighedstjek, som dit spørgsmål antyder, et btree-indeks på en hashværdi ved hjælp af md5(old_value)
eller hashtext(old_value)
ville være meget mere effektivt. Hvis du gør det, så husk at forsvare dig mod hashkollisioner sådan:
SELECT *
FROM record_changes_log_detail
WHERE hashtext(old_value) = hashtext('Gold Kerrison Neuro')
AND old_value = 'Gold Kerrison Neuro';
Det første prædikat giver dig hurtig indeksadgang. Den anden udelukker falske positiver. Kollisioner bør være yderst sjældne. Men muligt. Og muligheden vokser med bordets størrelse.
Relateret:
- SELECT-forespørgsel med DISTINCT på en tabelstruktur til grafer er meget langsom
- Hvad er den optimale datatype for et MD5-felt?
- Fuldtekstsøgning i CouchDB
Eller et hash-indeks, som du allerede har overvejet dig selv:
- Hvorfor er et Postgres 11-hash-indeks så stort?
(Her behøver du ikke bekymre dig om hash-kollisioner; håndteres internt.)