J'ai cette requête:
SELECT *
FROM location
WHERE to_tsvector('simple',unaccent2("city"))
@@ to_tsquery('simple',unaccent2('wroclaw'))
order by displaycount
J'en suis content:
"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"
Mais quand j'ajoute LIMIT, l'exécution prend plus de 2 secondes:
SELECT *
FROM location
WHERE to_tsvector('simple',unaccent2("city"))
@@ to_tsquery('simple',unaccent2('wroclaw'))
order by displaycount
limit 20
Explique:
"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"
Je pense que c'est un problème avec ORDER BY et LIMIT. Comment puis-je forcer PostgreSQL à utiliser l'index et à faire la commande à la fin?
La sous-requête n'aide pas:
SELECT *
FROM (
SELECT *
FROM location
WHERE to_tsvector('simple',unaccent2("city"))
@@ to_tsquery('simple',unaccent2('wroclaw'))
order by displaycount
) t
LIMIT 20;
ou:
SELECT *
FROM (
SELECT *
FROM location
WHERE to_tsvector('simple',unaccent2("city"))
@@ to_tsquery('simple',unaccent2('wroclaw'))
) t
order by displaycount
LIMIT 20;
Lorsque vous utilisez un ajustement postgresql LIMIT, il est prévu d'être optimal pour récupérer uniquement le sous-ensemble de lignes. Malheureusement, cela fait en quelque sorte un mauvais choix dans votre cas. Cela peut être dû au fait que les statistiques du tableau sont trop anciennes. Essayez de mettre à jour la statistique en émettant un emplacement ANALYSE DE VIDE;
Forcer l'utilisation d'index se fait normalement en interdisant l'utilisation d'analyses séquentielles (définissez enable_seqscan = false). Cependant, dans votre cas, il ne fait pas d'analyse séquentielle, il passe simplement à un index différent pour la requête avec LIMIT.
Dans le cas où l'analyse ne vous aiderait pas, pourriez-vous dire quelle version de postgresql vous utilisez? Aussi combien de lignes y a-t-il dans le tableau?
la source