Saya punya pertanyaan ini:
SELECT *
FROM location
WHERE to_tsvector('simple',unaccent2("city"))
@@ to_tsquery('simple',unaccent2('wroclaw'))
order by displaycount
Saya senang dengan itu:
"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"
Tetapi ketika saya menambahkan LIMIT, eksekusi membutuhkan lebih dari 2 detik:
SELECT *
FROM location
WHERE to_tsvector('simple',unaccent2("city"))
@@ to_tsquery('simple',unaccent2('wroclaw'))
order by displaycount
limit 20
Menjelaskan:
"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"
Saya pikir ini adalah masalah dengan ORDER BY dan LIMIT. Bagaimana saya bisa memaksa PostgreSQL untuk menggunakan indeks dan melakukan pemesanan di akhir?
Subquery tidak membantu:
SELECT *
FROM (
SELECT *
FROM location
WHERE to_tsvector('simple',unaccent2("city"))
@@ to_tsquery('simple',unaccent2('wroclaw'))
order by displaycount
) t
LIMIT 20;
atau:
SELECT *
FROM (
SELECT *
FROM location
WHERE to_tsvector('simple',unaccent2("city"))
@@ to_tsquery('simple',unaccent2('wroclaw'))
) t
order by displaycount
LIMIT 20;
Saat menggunakan postgresql LIMIT sesuaikan, rencananya akan optimal untuk hanya mengambil subset baris. Sayangnya itu entah bagaimana membuat pilihan yang salah dalam kasus Anda. Ini bisa jadi karena statistik untuk tabel terlalu lama. Coba perbarui statistik dengan menerbitkan lokasi VACUUM ANALYZE;
Memaksa penggunaan indeks biasanya dilakukan dengan melarang penggunaan pemindaian sekuensial (set enable_seqscan = false). Namun dalam kasus Anda itu tidak melakukan pemindaian berurutan itu hanya beralih ke indeks yang berbeda untuk kueri dengan LIMIT.
Jika analisis tidak membantu, bisakah Anda memberi tahu versi postgresql yang Anda gunakan? Juga berapa banyak baris yang ada di tabel?
sumber