Tại sao PostgreQuery 9.5 không sử dụng chỉ mục mới nhất của tôi cho ORDER BY, mặc dù nó sử dụng các chỉ số tương tự tốt?


7

(Theo dõi từ bài đăng này: Tại sao chỉ mục biểu thức PostgreSQL của tôi không được sử dụng khi tôi ĐẶT HÀNG B inNG trong một truy vấn con? )

PostgreQuery 9.5.

Tôi không thể tiết lộ chi tiết đầy đủ, nhưng tablecó 22 cột và 5 chỉ mục:

  1. khóa chính ('pk'), text(btree)
  2. khác text(btree)
  3. một timestamp with time zone(btree)
  4. một tsvector(gin)
  5. cái mới nhất của tôi, một bigint(btree)

(Từ bài trước bạn biết rằng tôi đã cố gắng để tránh tạo ra cột bổ sung này, và chỉ sử dụng một chỉ số biểu hiện - thêm hai integercột với nhau -. Nhưng không thành công Các bigintcột ở đây có lẽ có thể đã chỉ 'nguyên' nhưng tôi đã thực hiện một tạo ra nó, mất khoảng một giờ để thêm cột, điền vào nó và reindex, vì vậy tôi hy vọng điều này không liên quan nhưng chỉ đề cập đến nó trong trường hợp như vậy.)

Tất cả đều là btree ngoại trừ tsvector.

Tất cả các truy vấn sau chỉ mất 12ms và chỉ sử dụng một Index Scan:

  1. SELECT pk FROM table ORDER BY pk DESC LIMIT 10
  2. SELECT pk FROM table ORDER BY text_column DESC LIMIT 10
  3. SELECT pk FROM table ORDER BY timestamp_column DESC LIMIT 10

Nhưng nếu tôi cố gắng sử dụng bigintchỉ mục mới của mình cho ORDER BY:

SELECT pk FROM table ORDER BY bigint_column DESC LIMIT 10

... phải mất 2,7 giây và sử dụng Limit -> Sort -> Seq Scan.

Phương pháp "gian lận" của tôi là phương pháp gần nhất mà tôi dường như có thể sử dụng chỉ mục:

SELECT pk
FROM table
WHERE bigint_column > 1000000
ORDER BY bigint_column DESC LIMIT 10

Điều này mất 12ms và sử dụng Limit -> Sort -> Bitmap Heap Scan (bigint_column > 1000000) -> Bitmap Index Scan (bigint_column > 1000000).

Đây là sau VACUUM ANALYZEkhi thêm chỉ số.

Tôi nghĩ thật lạ khi chỉ số biểu hiện của tôi không được sử dụng trong câu hỏi khác. Bây giờ nó chỉ là một cột cũ đơn giản (tôi thậm chí chưa thêm những yếu tố cần thiết để thực sự đi theo con đường này.)

Tại sao chỉ mục mới nhất của tôi không được sử dụng, khi ba chỉ số kia hoạt động "tốt"? (Như đã chỉ ra trong các nhận xét tại https://dba.stackexchange.com/a/183290/28774 , Quét chỉ mục sẽ còn tốt hơn. Tôi không hiểu tại sao tất cả các truy vấn này sẽ không sử dụng ít nhất một Quét chỉ mục, huống chi là Quét chỉ mục, thay vì Quét Seq đầy đủ.)

Định nghĩa chỉ mục có DESC NULLS LAST(mặc dù đó là cột không thể rỗng.)

Câu trả lời:


7

Trong PostgreSQL, một chỉ mục DESC NULLS LASTkhông thể được sử dụng để đáp ứng một ORDER BYchỉ số DESC NULLS FIRST(bao gồm cả việc đặt hàng đơn giản chỉ DESCvì điều đó ngụ ý NULLS FIRST). Đây là trường hợp ngay cả khi cột được xác định là NOT NULL.

Bạn có thể xây dựng lại chỉ mục hoặc (vì bạn biết cột không phải là null), bạn có thể thêm NULLS LASTvào truy vấn của ORDER BYmình để làm cho nó khớp với chỉ mục hiện có.

Lưu ý rằng PostgreSQLkhông biết làm thế nào để theo dõi một chỉ mục ngược, vì vậy một chỉ mục mặc định (được ngầm định ASC NULLS LAST) cũng có thể đáp ứng DESC NULLS FIRSTtruy vấn của bạn . Do đó, việc chỉ định DESC trong một chỉ mục hiếm khi rất quan trọng, nhưng điều quan trọng là chỉ định kết thúc sắp xếp NULLS nào.


Tôi cũng gặp vấn đề này với chỉ số GiST. Nó chỉ có thể được định nghĩa là ASC (không chắc là NULLS FIRST hay LAST). Dù bằng cách nào, việc có chỉ mục như postgres này dường như không muốn đặt hàng bởi DESC mà không thực hiện quét seq. Có lời khuyên nào không?
Kevin Parker
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.