wie im Titel erwähnt würde ich gerne eine Jokersuche auf meine Index-Spalte nutzen.
Dazu habe ich mir einen Index über die unten stehenden Befehle erstellt.
Soweit ich das verstanden habe, wir nun der Inhalt der ursprünglichen Spalte gefiltert und die Stammform der Wörter in die tsvector-Spalte übernommen, auf die man später seine
Suchabfrage abfeuert.
Mögliches select wäre dann:
SELECT * FROM <tbl_name> WHERE <index_col> @@ to_tsquery(‘default_ger’, ‘Suchbegriff1 | Suchbegriff2’);
Ich würde jetzt gerne eine Jokersuche machen und z.B. nach ‘Suchbe%’ suchen.
So funktioniert das nur leider nicht. Ich erhalte keine Treffer mehr.
In der Dokumentation steht leider auch nichts dazu drin.
Ich hoffe Ihr könnt mir weiterhelfen.
Vielen Dank im Voraus.
[PostgreSQL Version 9.0]
Gruß Manuel
Volltext Index erstellen:
CREATE TEXT SEARCH CONFIGURATION default_ger (COPY=german);
ALTER TABLE <tbl_name> ADD COLUMN <index_col> tsvector;
UPDATE <tbl_name> SET <index_col>=to_tsvector(‘default_ger’, <tbl_spalte>);
VACUUM FULL ANALYZE;
CREATE INDEX <index_name> ON memo USING gin(<tbl_name>); --gin bzw. gist
VACUUM FULL ANALYZE;
Nachtrag: Soweit ich das jetzt recherchiert habe, kann man keine Substring-Suche (Jokersuche) ausführen.
Was mit trotzdem stutzig macht ist folgendes:
Eigentlich hatte ich eine Verbesserung der Abfragedauer durch die Indizierung erwartet.
Zum Testen habe ich mir hierfür 3 Datenbanken (20.000 Einträge in meiner Tabelle) erstellt.
Ohne Indize
Mit Hash-Indize
Gist/Gin-Indize
Auf 1. und 2. habe ich ein Testselekt mit LIKE ausgeführt.
Auf 3. habe ich das Testselekt mit der Vorgegeben Syntax verwendet. (SELECT * FROM <tbl_name> WHERE <index_col> @@ to_tsquery(‘default_ger’, ‘Suchbegriff1 | Suchbegriff2’)
Konnte unter 1. und 2. keinen Unterschied zur Abfragedauer feststellen.
Auf 3. war das Testselekt sogar langsamer als bei 1. und 2.
Ich hätte jetzt zumindest zwischen 1. und 2. einen deutlichen unterschied erwartet…
Kann mir da vielleicht jemand sagen wieso ich solche Ergebnisse gekriegt habe?
Ich dachte durch die Indizes wird der Zugriff beschleuningt, was eben nicht mit meinen Ergebnissen übereinstimmt
Tatsächlich wurden alle Datensätze als Treffermenge ausgegeben.
Also soweit man beim Gin/Gist Index nicht die komplette Datenmenge als Ergebnis hat, verwendet er den Index auch. Das ist schonmal gut.
Der HASH-Index wird aber so gut wie nie benutzt.
In den FAQs aus dem PG Wiki, steht z.B. dass LIKE suchen generell nicht mit ‘%’ beginnen dürfen.
Beispiel:
SELECT * FROM memo
WHERE memo_text like ‘%server%’
test=*# \d words
Table "public.words"
Column | Type | Modifiers
--------+------+-----------
w | text |
Indexes:
"idx_w" btree (w)
test=*# explain select * from words where w like 'foo%';
QUERY PLAN
----------------------------------------------------------
Seq Scan on words (cost=0.00..8460.29 rows=48 width=10)
Filter: (w ~~ 'foo%'::text)
(2 rows)
test=*# create index idx_w2 on words(w text_pattern_ops);
CREATE INDEX
test=*# explain select * from words where w like 'foo%';
QUERY PLAN
---------------------------------------------------------------------------
Index Only Scan using idx_w2 on words (cost=0.00..8.34 rows=48 width=10)
Index Cond: ((w ~>=~ 'foo'::text) AND (w ~<~ 'fop'::text))
Filter: (w ~~ 'foo%'::text)
(3 rows)
Indexes:idx_w" btree (w) <-- Hab ich auch, einfacher BTree Index create index idx_w2 on words(w text_pattern_ops); <-- Kann ich nicht erstellen: FEHLER: Indexzeile benötigt 9224 Bytes, Maximalgröße ist 8191
Vielleicht kannst du mir nochmal erklären wieso ich überhaupt 2 Indizes erstellen muss/soll ?