Tại sao PostgreSQL thực hiện quét tuần tự trên cột được lập chỉ mục?


150

Ví dụ rất đơn giản - một bảng, một chỉ mục, một truy vấn:

CREATE TABLE book
(
  id bigserial NOT NULL,
  "year" integer,
  -- other columns...
);

CREATE INDEX book_year_idx ON book (year)

EXPLAIN
 SELECT *
   FROM book b
  WHERE b.year > 2009

đưa cho tôi:

Seq Scan on book b  (cost=0.00..25663.80 rows=105425 width=622)
  Filter: (year > 2009)

Tại sao nó KHÔNG thực hiện quét chỉ mục thay thế? Tôi đang thiếu gì?

Câu trả lời:


222

Nếu CHỌN trả về hơn 5-10% tất cả các hàng trong bảng, thì việc quét tuần tự nhanh hơn nhiều so với quét chỉ mục.

Điều này là do quét chỉ mục yêu cầu một số thao tác IO cho mỗi hàng (tra cứu hàng trong chỉ mục, sau đó truy xuất hàng từ heap). Trong khi đó, việc quét tuần tự chỉ yêu cầu một IO cho mỗi hàng - hoặc thậm chí ít hơn vì một khối (trang) trên đĩa chứa nhiều hơn một hàng, do đó, nhiều hơn một hàng có thể được tìm nạp với một thao tác IO.

Btw: điều này cũng đúng với các DBMS khác - một số tối ưu hóa như "quét chỉ mục" bị gạt sang một bên (nhưng đối với CHỌN * rất khó có khả năng DBMS sẽ thực hiện "quét chỉ mục")


12
5-10% phụ thuộc vào một vài cài đặt cấu hình và lưu trữ dữ liệu. Đó không phải là một con số khó.
Frank Heikens

6
@Frank: đó là lý do tại sao tôi nói "khoảng" :) Nhưng cảm ơn vì đã chỉ ra
a_horse_with_no_name

5
Ngoài ra, quét tuần tự có thể yêu cầu một số trang từ heap cùng một lúc và yêu cầu kernel tìm nạp đoạn tiếp theo trong khi nó hoạt động trên trang hiện tại - quét chỉ mục tìm nạp một trang cùng một lúc. (Quét bitmap làm thỏa hiệp giữa hai loại, bạn thường thấy rằng xuất hiện trong kế hoạch cho các truy vấn không đủ chọn lọc để quét chỉ mục, nhưng vẫn không chọn lọc để quét toàn bộ bảng)
araqnid

4
Câu hỏi thú vị là làm thế nào cơ sở dữ liệu biết có bao nhiêu hàng truy vấn sẽ trả về mà không thực hiện trước? Nó có lưu trữ các số liệu thống kê như số lượng giá trị khác nhau so với kích thước bảng ở đâu đó không?
Laurent Grégoire

7
@ LaurentGrégoire: có, cơ sở dữ liệu lưu trữ số liệu thống kê về số lượng hàng và phân phối giá trị. Xem hướng dẫn để biết chi tiết: postgresql.org/docs/civerse/static/planner-stats.html
a_horse_with_no_name


0

Trong quét chỉ mục, đọc đầu nhảy từ hàng này sang hàng khác chậm hơn 1000 lần so với đọc khối vật lý tiếp theo (trong lần quét tuần tự).

Vì vậy, nếu (số lượng bản ghi được truy xuất * 1000) nhỏ hơn tổng số bản ghi, quá trình quét chỉ mục sẽ hoạt động tốt hơn.


0

@a_horse_with_no_name đã giải thích nó khá tốt. Ngoài ra nếu bạn thực sự muốn sử dụng quét chỉ mục, bạn thường nên sử dụng phạm vi giới hạn trong mệnh đề where. ví dụ: năm> 2019 và năm <2020.

Rất nhiều lần thống kê không được cập nhật trên một bảng và có thể không thực hiện được do các ràng buộc. Trong trường hợp này, trình tối ưu hóa sẽ không biết cần bao nhiêu hàng trong năm> 2019. Do đó, nó chọn một lần quét liên tiếp thay cho kiến ​​thức đầy đủ. Phân vùng bị ràng buộc sẽ giải quyết vấn đề hầu hết thời gian.

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.