PostgreSQL
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> PostgreSQL

PostgreSQL:Tại sao truy vấn này không sử dụng chỉ mục của tôi?

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 ab 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 ab đ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 abc ) 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 abd 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 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:



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. lỗi lệnh sử dụng alembic không thể tìm thấy mã định danh

  2. Các cột Cơ sở dữ liệu Trong Chọn hoặc tạo các câu lệnh

  3. Hết thời gian chờ kết nối PostgreSQL

  4. Thêm đối tượng Postgres vào Template1

  5. Nhận cá thể IPAddr từ biểu diễn json của nó