PostgreSQL
 sql >> Datenbank >  >> RDS >> PostgreSQL

Suche nach Ausdrucksindizes

Es ist genau so, wie Sie es an anderer Stelle von jjanes gelesen haben:Ein Ausdrucksindex wird nur berücksichtigt, wenn der Ausdruck im Abfrageprädikat genau übereinstimmt. Der Postgres-Abfrageplaner ist keine KI. Es würde den Zweck, Abfragen schnell zu machen, schnell zunichte machen, wenn die Planung zu lange dauert.

Sie können Ihren Index ein wenig optimieren, falls das ein Trost ist. left() ist einfacher und schneller als substring() :

CREATE INDEX record_changes_log_detail_old_value_ix_btree
ON record_changes_log_detail (left(old_value,1024) text_pattern_ops);

Außerdem gibt es eine maximale Zeilengröße von 2704 Byte für Btree-Indizes, kein "2172-Zeichen-Limit für B-Trees" .

Am wichtigsten ist, dass nur für Gleichheitsprüfungen, wie Ihre Frage vorschlägt, ein btree-Index für einen Hash-Wert mit md5(old_value) verwendet wird oder hashtext(old_value) wäre viel effizienter. Denken Sie in diesem Fall daran, sich gegen Hash-Kollisionen zu verteidigen etwa so:

SELECT *
FROM   record_changes_log_detail 
WHERE  hashtext(old_value) = hashtext('Gold Kerrison Neuro')
AND    old_value = 'Gold Kerrison Neuro';

Das erste Prädikat ermöglicht Ihnen einen schnellen Indexzugriff. Die zweite schließt falsch positive Ergebnisse aus. Kollisionen sollten extrem selten sein. Aber möglich. Und die Möglichkeit wächst mit der Größe des Tisches.

Verwandte:

  • SELECT-Abfrage mit DISTINCT auf eine Tabellenstruktur für Graphen ist sehr langsam
  • Was ist der optimale Datentyp für ein MD5-Feld?
  • Volltextsuche in CouchDB

Oder ein Hash-Index, wie Sie ihn bereits in Erwägung gezogen haben:

  • Warum ist ein Postgres 11-Hash-Index so groß?

(Hier müssen Sie sich keine Gedanken über Hash-Kollisionen machen; wird intern behandelt.)