ĐẶT HÀNG chậm với GIỚI HẠN


11

Tôi có truy vấn này:

SELECT * 
FROM location 
WHERE to_tsvector('simple',unaccent2("city"))
   @@ to_tsquery('simple',unaccent2('wroclaw')) 
order by displaycount

Tôi hài lòng với nó:

"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"

Nhưng khi tôi thêm GIỚI HẠN, việc thực thi mất hơn 2 giây:

SELECT * 
FROM location 
WHERE to_tsvector('simple',unaccent2("city"))
   @@ to_tsquery('simple',unaccent2('wroclaw')) 
order by displaycount 
limit 20

Giải thích:

"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"

Tôi nghĩ rằng đó là một số vấn đề với ĐẶT HÀNG BỞI và GIỚI HẠN. Làm cách nào tôi có thể buộc PostgreSQL sử dụng chỉ mục và thực hiện đặt hàng ở cuối?

Subquery không giúp đỡ:

SELECT * 
FROM (
    SELECT * 
    FROM location 
    WHERE to_tsvector('simple',unaccent2("city"))
       @@ to_tsquery('simple',unaccent2('wroclaw')) 
    order by displaycount
) t 
LIMIT 20;

hoặc là:

SELECT * 
FROM (
    SELECT * 
    FROM location 
    WHERE to_tsvector('simple',unaccent2("city"))
       @@ to_tsquery('simple',unaccent2('wroclaw'))
) t 
order by displaycount 
LIMIT 20;

Câu trả lời:


12

Tôi đoán là điều này sẽ sửa chữa truy vấn của bạn:

SELECT * 
FROM   location 
WHERE     to_tsvector('simple',unaccent2(city))
       @@ to_tsquery('simple',unaccent2('wroclaw')) 
ORDER  BY to_tsvector('simple',unaccent2(city))
       @@ to_tsquery('simple',unaccent2('wroclaw')) DESC
         ,displaycount 
LIMIT  20;

Tôi lặp lại WHEREđiều kiện như là phần tử đầu tiên của ORDER BYmệnh đề - vốn là dự phòng logic, nhưng nên giữ cho trình hoạch định truy vấn giả định rằng sẽ tốt hơn khi xử lý các hàng theo chỉ mục location_displaycount_index- hóa ra đắt hơn nhiều.

Vấn đề cơ bản là trình lập kế hoạch truy vấn rõ ràng đã đánh giá sai sự chọn lọc và / hoặc chi phí cho WHEREtình trạng của bạn . Tôi chỉ có thể suy đoán tại sao lại như vậy.

Bạn có chạy autovacuum - cũng nên chăm sóc chạy ANALYZEtrên bàn của bạn? Do đó, bảng thống kê của bạn có được cập nhật không? Bất kỳ hiệu ứng nếu bạn chạy:

ANALYZE location;

Và thử lại?

Nó cũng có thể là sự chọn lọc của @@nhà điều hành đang bị đánh giá sai. Tôi sẽ tưởng tượng rằng rất khó để ước tính vì lý do hợp lý.


Nếu truy vấn của tôi không giải quyết được vấn đề và nói chung để xác minh lý thuyết cơ bản, hãy thực hiện một trong hai điều sau:

Cái sau ít xâm phạm hơn và chỉ ảnh hưởng đến phiên hiện tại. Nó để lại các phương thức bitmap heap scanbitmap index scanmở, được sử dụng bởi kế hoạch nhanh hơn.
Sau đó chạy lại truy vấn.

BTW: Nếu lý thuyết là âm thanh, truy vấn của bạn (như bạn có bây giờ) sẽ nhanh hơn nhiều với thuật ngữ tìm kiếm ít chọn lọc hơn trong điều kiện FTS - trái với những gì bạn có thể mong đợi. Thử nó.


1
Các truy vấn hoạt động. Tắt indexscan cũng hoạt động. ANALYZE không hoạt động. Cảm ơn bạn rất nhiều vì câu trả lời toàn diện.
ziri

0

Khi sử dụng một postgresql LIMIT, điều chỉnh kế hoạch của nó là tối ưu để chỉ truy xuất tập hợp con của hàng. Thật không may nó bằng cách nào đó làm cho một lựa chọn sai trong trường hợp của bạn. Điều này có thể là do số liệu thống kê cho bảng quá cũ. Hãy thử cập nhật thống kê bằng cách phát hành vị trí VACUUM ANALYZE;

Buộc sử dụng các chỉ mục thường được thực hiện bằng cách không cho phép sử dụng quét tuần tự (đặt enable_seqscan = false). Tuy nhiên, trong trường hợp của bạn, nó không thực hiện quét tuần tự, nó chỉ chuyển sang một chỉ mục khác cho truy vấn có GIỚI HẠN.

Trong trường hợp phân tích không giúp bạn có thể cho biết phiên bản postgresql nào bạn đang sử dụng không? Ngoài ra có bao nhiêu hàng trong bảng?


Phân tích đã không giúp đỡ. Bảng này có khoảng 36000 hàng và tôi đang sử dụng postgresql 9.1.
ziri
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.