Như bạn đã nhận ra, vấn đề liên quan đến việc sử dụng các toán tử không phải là bằng. Chỉ có thể sử dụng chỉ mục một cách hiệu quả nhất cho các cột ngoài cùng bên trái được so sánh với bằng (cộng với một điều kiện phạm vi).
Trong ví dụ của bạn:
create index i on t (a,b,c,d);
where a=1 and b=11 and c!=5 and d<8;
Nó chỉ có thể sử dụng chỉ mục cho a
và b
một cách hiệu quả. Điều đó có nghĩa là DB tìm nạp tất cả các hàng khớp với a
và b
điều kiện và sau đó kiểm tra từng hàng với các điều kiện còn lại.
Khi bạn thay đổi bộ lọc trên c
để bằng, nó tìm nạp (có khả năng) ít hàng hơn (chỉ những hàng phù hợp với a
và b
và c
) và sau đó kiểm tra (ít hơn) các hàng đó với d
lọc. Sử dụng chỉ mục hiệu quả hơn trong trường hợp này.
Nói chung, công cụ lập kế hoạch truy vấn PostgreSQL đánh giá cả hai tùy chọn:(1) sử dụng chỉ mục; (2) thực hiện quét SeqScan. Đối với cả hai, nó tính toán một giá trị chi phí - càng cao thì hiệu suất mong đợi càng kém. Do đó, nó lấy cái có giá trị chi phí nhỏ hơn. Đây là cách nó quyết định sử dụng chỉ mục hay không, không có ngưỡng cố định.
Cuối cùng, được viết "cộng với một điều kiện phạm vi" ở trên. Điều đó có nghĩa là nó không chỉ có thể sử dụng chỉ mục theo cách hiệu quả nhất nếu bạn đang sử dụng các dấu bằng mà còn cho một điều kiện phạm vi duy nhất.
Xét rằng bạn có một điều kiện phạm vi duy nhất trong truy vấn của mình, tôi khuyên bạn nên thay đổi chỉ mục như sau:
create index i on t (a,b,d,c);
Bây giờ nó có thể sử dụng các bộ lọc trên a
và b
và d
hiệu quả với chỉ mục và chỉ cần lọc các hàng có c!=5
. Mặc dù chỉ mục này có thể được sử dụng hiệu quả hơn cho truy vấn của bạn như là chỉ mục gốc của bạn, nhưng điều đó không tự động có nghĩa là PG sẽ sử dụng nó. Nó phụ thuộc vào ước tính chi phí. Nhưng hãy thử.
Cuối cùng, nếu điều này không nhanh thì nên và giá trị 5
bạn đang sử dụng trong biểu thức c!=5
là hằng số, bạn có thể coi là chỉ mục một phần:
create index i on t (a,b,d)
where c!=5;
Bạn cũng có thể làm điều đó với tất cả các cột khác, nếu các giá trị bạn so sánh với chúng là hằng số.
Tài liệu tham khảo: