Ich habe diese Frage:
SELECT *
FROM location
WHERE to_tsvector('simple',unaccent2("city"))
@@ to_tsquery('simple',unaccent2('wroclaw'))
order by displaycount
Ich bin zufrieden damit:
"Sort (cost=3842.56..3847.12 rows=1826 width=123) (actual time=1.915..2.084 rows=1307 loops=1)"
" Sort Key: displaycount"
" Sort Method: quicksort Memory: 206kB"
" -> Bitmap Heap Scan on location (cost=34.40..3743.64 rows=1826 width=123) (actual time=0.788..1.208 rows=1307 loops=1)"
" Recheck Cond: (to_tsvector('simple'::regconfig, unaccent2((city)::text)) @@ '''wroclaw'''::tsquery)"
" -> Bitmap Index Scan on location_lower_idx (cost=0.00..33.95 rows=1826 width=0) (actual time=0.760..0.760 rows=1307 loops=1)"
" Index Cond: (to_tsvector('simple'::regconfig, unaccent2((city)::text)) @@ '''wroclaw'''::tsquery)"
"Total runtime: 2.412 ms"
Wenn ich jedoch LIMIT hinzufüge, dauert die Ausführung länger als 2 Sekunden:
SELECT *
FROM location
WHERE to_tsvector('simple',unaccent2("city"))
@@ to_tsquery('simple',unaccent2('wroclaw'))
order by displaycount
limit 20
Erklären:
"Limit (cost=0.00..1167.59 rows=20 width=123) (actual time=2775.452..2775.643 rows=20 loops=1)"
" -> Index Scan using location_displaycount_index on location (cost=0.00..106601.25 rows=1826 width=123) (actual time=2775.448..2775.637 rows=20 loops=1)"
" Filter: (to_tsvector('simple'::regconfig, unaccent2((city)::text)) @@ '''wroclaw'''::tsquery)"
"Total runtime: 2775.693 ms"
Ich denke, dass es ein Problem mit ORDER BY und LIMIT ist. Wie kann ich PostgreSQL zwingen, den Index zu verwenden und die Bestellung am Ende durchzuführen?
Unterabfrage hilft nicht:
SELECT *
FROM (
SELECT *
FROM location
WHERE to_tsvector('simple',unaccent2("city"))
@@ to_tsquery('simple',unaccent2('wroclaw'))
order by displaycount
) t
LIMIT 20;
oder:
SELECT *
FROM (
SELECT *
FROM location
WHERE to_tsvector('simple',unaccent2("city"))
@@ to_tsquery('simple',unaccent2('wroclaw'))
) t
order by displaycount
LIMIT 20;
Wenn Sie eine LIMIT-Postgresql-Anpassung verwenden, ist der Plan optimal, um nur die Teilmenge der Zeile abzurufen. Leider trifft es in Ihrem Fall irgendwie eine falsche Wahl. Dies kann daran liegen, dass die Statistiken für die Tabelle zu alt sind. Versuchen Sie, die Statistik zu aktualisieren, indem Sie den Speicherort VACUUM ANALYZE angeben.
Das Erzwingen der Verwendung von Indizes erfolgt normalerweise, indem die Verwendung von sequentiellen Scans nicht zugelassen wird (setzen Sie enable_seqscan = false). In Ihrem Fall wird jedoch kein sequentieller Scan durchgeführt, sondern nur mit LIMIT zu einem anderen Index für die Abfrage gewechselt.
Falls die Analyse nicht hilft, können Sie dann feststellen, welche Version von postgresql Sie verwenden? Wie viele Zeilen enthält die Tabelle?
quelle