Ngoài câu trả lời thấu đáo của Craig, tôi muốn thêm rằng bìa của cuốn sách mà bạn tham khảo nói:
Bao gồm máy chủ Oracle, DB2 & SQL
Vì vậy, tôi không tin tưởng nó sẽ là một nguồn tư vấn tuyệt vời về PostgreSQL nói riêng. Mỗi RDBMS có thể khác nhau đáng ngạc nhiên!
Tôi hơi bối rối về câu hỏi ban đầu của bạn, nhưng đây là một ví dụ cho thấy phần của cuốn sách không chính xác 100%. Để tránh nhầm lẫn thêm, đây là toàn bộ đoạn có liên quan, bạn có thể xem nó trong Tìm kiếm Sách của Google .
Cơ sở dữ liệu giả định rằng Indexed_Col IS KHÔNG NULL bao phủ phạm vi quá lớn sẽ không hữu ích, vì vậy cơ sở dữ liệu sẽ không hướng đến một chỉ mục từ điều kiện này. Trong các trường hợp hiếm hoi, việc có bất kỳ giá trị không phải nào là rất hiếm khi quét phạm vi chỉ mục trên tất cả các giá trị không có giá trị có thể có lợi. Trong các trường hợp như vậy, nếu bạn có thể tìm ra giới hạn dưới hoặc trên an toàn cho phạm vi của tất cả các giá trị có thể, bạn có thể kích hoạt quét phạm vi với một điều kiện như positive_ID_Column> -1 hoặc Date_Column> TO_DATE ('0001/01/01' , 'YYYY / MM / DD').
Postgres thực sự có thể (trong trường hợp giả định sau) sử dụng một chỉ mục để đáp ứng IS NOT NULL
các truy vấn mà không cần thêm các khoảng quét quét phạm vi như đề xuất Positive_ID_Column > -1
. Xem các nhận xét về câu hỏi của Craig để biết lý do tại sao Postgres chọn chỉ mục này trong trường hợp cụ thể này và lưu ý về việc sử dụng chỉ mục một phần.
CREATE TABLE bar (a int);
INSERT INTO bar (a) SELECT NULL FROM generate_series(1,1000000);
INSERT INTO bar (a) VALUES (1);
CREATE INDEX bar_idx ON bar (a);
EXPLAIN ANALYZE SELECT * FROM bar WHERE a IS NOT NULL;
QUERY PLAN
------------------------------------------------------------------------------------------------------------------
Index Only Scan using bar_idx on bar (cost=0.42..8.44 rows=1 width=4) (actual time=0.094..0.095 rows=1 loops=1)
Index Cond: (a IS NOT NULL)
Heap Fetches: 1
Total runtime: 0.126 ms
(4 rows)
Đây là Postgres 9.3, nhưng tôi tin rằng kết quả sẽ gần như tương tự vào ngày 9.1, mặc dù nó sẽ không sử dụng "Quét chỉ mục lục".
Chỉnh sửa: Tôi thấy bạn đã làm rõ câu hỏi ban đầu của mình và rõ ràng bạn đang tự hỏi tại sao Postgres không sử dụng chỉ mục trong một ví dụ đơn giản như:
CREATE TABLE my_table(
a varchar NOT NULL
);
CREATE INDEX ix_my_table ON my_table(a);
SELECT a from my_table;
Có lẽ bởi vì bạn không có bất kỳ hàng nào trong bảng. Vì vậy, thêm một số dữ liệu thử nghiệm và ANALYZE my_table;
.