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

Tác động hiệu suất của chế độ xem lên chức năng tổng hợp so với giới hạn tập hợp kết quả

Các truy vấn không hoàn toàn tương đương

Để làm cho bối cảnh rõ ràng:

  • max(id) loại trừ NULL các giá trị. Nhưng ORDER BY ... LIMIT 1 không.
  • NULL các giá trị sắp xếp cuối cùng theo thứ tự sắp xếp tăng dần và đầu tiên theo thứ tự giảm dần. Vì vậy, một Index Scan Backward có thể không tìm thấy giá trị lớn nhất (theo max() ) đầu tiên, nhưng bất kỳ số nào của NULL giá trị.

Tương đương chính thức của:

SELECT max(id) FROM testview;

không phải là:

SELECT id FROM testview ORDER BY id DESC LIMIT 1;

nhưng:

SELECT id FROM testview ORDER BY id DESC NULLS LAST LIMIT 1;

Truy vấn thứ hai không nhận được kế hoạch truy vấn nhanh. Nhưng nó sẽ có chỉ mục với thứ tự sắp xếp phù hợp:(id DESC NULLS LAST) .

Điều đó khác với các hàm tổng hợp min()max() . Những người đó có được một kế hoạch nhanh chóng khi nhắm mục tiêu bảng test1 trực tiếp sử dụng chỉ mục PK thuần túy trên (id) . Nhưng không phải khi dựa trên chế độ xem (hoặc trực tiếp truy vấn nối bên dưới - chế độ xem không phải là trình chặn). Chỉ mục sắp xếp các giá trị NULL vào đúng vị trí hầu như không có tác dụng.

Chúng tôi biết rằng id trong truy vấn này không bao giờ được NULL . Cột được xác định NOT NULL . Và tham gia trong chế độ xem thực sự là một INNER JOIN mà không thể giới thiệu NULL giá trị cho id .
Chúng tôi cũng biết rằng chỉ mục trên test.id không được chứa giá trị NULL.
Nhưng công cụ lập kế hoạch truy vấn Postgres không phải là AI. (Cũng không nên cố gắng, điều đó có thể nhanh chóng vượt khỏi tầm tay.) Tôi thấy hai thiếu sót :

  • min()max() chỉ nhận được kế hoạch nhanh khi nhắm mục tiêu bảng, bất kể thứ tự sắp xếp chỉ mục, điều kiện chỉ mục được thêm vào:Index Cond: (id IS NOT NULL)
  • ORDER BY ... LIMIT 1 chỉ nhận được kế hoạch nhanh chóng với thứ tự sắp xếp chỉ mục khớp chính xác.

Không chắc, liệu điều đó có thể được cải thiện (dễ dàng) hay không.

db <> fiddle tại đây - thể hiện tất cả những điều trên

Chỉ mục

Chỉ mục này hoàn toàn vô dụng:

CREATE INDEX ON "test" ("id");

PK trên test.id được triển khai với một chỉ mục duy nhất trên cột, chỉ mục này đã bao gồm mọi thứ mà chỉ mục bổ sung có thể làm cho bạn.

Có thể còn nhiều điều nữa, đang chờ câu hỏi sáng tỏ.

Trường hợp thử nghiệm bị biến dạng

Trường hợp thử nghiệm quá xa so với trường hợp sử dụng thực tế để có ý nghĩa.

Trong thiết lập thử nghiệm, mỗi bảng có 100k hàng, không có gì đảm bảo rằng mọi giá trị trong joincol có một kết quả phù hợp ở phía bên kia và cả hai cột đều có thể là NULL

Trường hợp thực của bạn có 10 triệu hàng trong table1 và <100 hàng trong table2 , mọi giá trị trong table1.joincol có một kết quả phù hợp trong table2.joincol , cả hai đều được định nghĩa NOT NULLtable2.joincol là duy nhất. Mối quan hệ một-nhiều cổ điển. Phải có UNIQUE ràng buộc trên table2.joincol và một ràng buộc FK t1.joincol --> t2.joincol .

Nhưng đó là tất cả hiện tại của câu hỏi. Chờ cho đến khi nó được dọn sạch.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Nhập tệp từ PostgreSQL sang R

  2. Thay đổi giá trị bắt đầu của một chuỗi - Postgresql

  3. thay thế cho chỉ mục bitmap trong postgresql

  4. Hàm LEAST () trong PostgreSQL

  5. pg_stat_activity không cập nhật trong một thủ tục hoặc giao dịch