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

Các truy vấn (CHỌN) được lên kế hoạch khi nào?

Tôi không thể nói về bản thân giao diện Perl phía máy khách nhưng tôi có thể làm sáng tỏ về phía máy chủ PostgreSQL.

PostgreSQL có các câu lệnh chuẩn bị và các câu lệnh chưa chuẩn bị. Các câu lệnh chưa chuẩn bị được phân tích cú pháp, lập kế hoạch và thực thi ngay lập tức. Họ cũng không không hỗ trợ thay thế tham số. Trên psql đơn giản bạn có thể hiển thị kế hoạch truy vấn của họ như sau:

tmpdb> explain select * from sometable where flag = true;

Mặt khác, có các câu lệnh được chuẩn bị sẵn:Chúng thường được (xem "ngoại lệ" bên dưới) phân tích cú pháp và lập kế hoạch trong một bước và thực thi trong bước thứ hai. Chúng có thể được thực thi lại nhiều lần với các tham số khác nhau, vì chúng thực hiện hỗ trợ thay thế tham số. Tương đương trong psql đây có phải là:

tmpdb> prepare foo as select * from sometable where flag = $1;
tmpdb> explain execute foo(true);

Bạn có thể thấy rằng kế hoạch khác với kế hoạch trong tuyên bố chưa chuẩn bị, bởi vì việc lập kế hoạch đã diễn ra trong prepare giai đoạn như được mô tả trong tài liệu cho CHUẨN BỊ :

Điều này cũng có nghĩa là kế hoạch là KHÔNG được tối ưu hóa cho các tham số được thay thế:Trong các ví dụ đầu tiên có thể sử dụng chỉ mục cho flag bởi vì PostgreSQL biết rằng trong một triệu mục nhập chỉ có mười mục có giá trị true . Lý luận này là không thể khi PostgreSQL sử dụng một câu lệnh đã chuẩn bị sẵn. Trong trường hợp đó, một kế hoạch được tạo ra sẽ hoạt động tốt nhất có thể đối với tất cả các giá trị tham số có thể có. Điều này có thể loại trừ chỉ mục được đề cập vì tìm nạp phần tốt hơn của bảng hoàn chỉnh thông qua truy cập ngẫu nhiên (do chỉ mục) chậm hơn so với quét tuần tự thuần túy. CHUẨN BỊ doc xác nhận điều này:

BTW - Về bộ nhớ đệm kế hoạch, CHUẨN BỊ doc cũng có vài điều muốn nói:

Ngoài ra, không có bộ nhớ đệm kế hoạch tự động và không có bộ nhớ đệm / sử dụng lại qua nhiều kết nối.

NGOẠI LỆ :Tôi đã đề cập đến "thường". psql được hiển thị các ví dụ không phải là thứ mà bộ điều hợp máy khách như Perl DBI thực sự sử dụng. Nó sử dụng một giao thức nhất định . Ở đây thuật ngữ "truy vấn đơn giản" tương ứng với "truy vấn chưa chuẩn bị" trong psql , thuật ngữ " truy vấn mở rộng "tương ứng với" truy vấn đã chuẩn bị "với một ngoại lệ:Có sự khác biệt giữa (một)" câu lệnh không được đặt tên "và (có thể nhiều)" câu lệnh được đặt tên ". Về các câu lệnh được đặt tên, doc nói:

và cả:

Vì vậy, trong trường hợp này, việc lập kế hoạch được thực hiện mà không có các tham số như mô tả ở trên cho PREPARE - không có gì mới.

Ngoại lệ được đề cập là "tuyên bố không tên". Tài liệu nói:

Và đây là lợi ích:Mặc dù câu lệnh chưa đặt tên là "chuẩn bị" (tức là có thể có thay thế tham số), nó cũng có thể điều chỉnh kế hoạch truy vấn cho phù hợp với các tham số thực tế.

BTW:Việc xử lý chính xác câu lệnh không có tên đã thay đổi nhiều lần trong các bản phát hành trước đây của máy chủ PostgreSQL. Bạn có thể tra cứu các tài liệu cũ để biết chi tiết nếu bạn thực sự muốn.

Cơ sở lý luận - Perl / bất kỳ khách hàng nào :

Làm thế nào một khách hàng như Perl sử dụng giao thức là một câu hỏi hoàn toàn khác. Một số ứng dụng khách như trình điều khiển JDBC cho Java về cơ bản nói:Ngay cả khi lập trình viên sử dụng câu lệnh đã chuẩn bị, năm (hoặc lâu hơn) lần thực thi đầu tiên được ánh xạ nội bộ đến một "truy vấn đơn giản" (tức là không được chuẩn bị trước), sau đó trình điều khiển chuyển sang " câu lệnh được đặt tên ”.

Vì vậy, khách hàng có những lựa chọn sau:

  • Bắt buộc (lại) lập kế hoạch mỗi lần bằng cách sử dụng giao thức "truy vấn đơn giản".
  • Kế hoạch một lần, thực thi nhiều lần bằng cách sử dụng giao thức "truy vấn mở rộng" và "câu lệnh được đặt tên" (kế hoạch có thể không tốt vì việc lập kế hoạch được thực hiện mà không có tham số).
  • Phân tích cú pháp một lần, lập kế hoạch cho mỗi lần thực thi (với phiên bản PostgreSQL hiện tại) bằng cách sử dụng giao thức "truy vấn mở rộng" và "câu lệnh không tên" và tuân theo một số điều khác (cung cấp một số thông số trong quá trình "phân tích cú pháp")
  • Chơi các thủ thuật hoàn toàn khác như trình điều khiển JDBC.

Perl hiện đang làm gì:Tôi không biết. Nhưng "cá trích đỏ" được đề cập không phải là rất khó xảy ra.




  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 khi tạo tiện ích mở rộng không phù hợp trên PostgreSQL

  2. Tiếp tục giao dịch sau lỗi vi phạm khóa chính

  3. sql - nhóm theo phạm vi để bao gồm các phạm vi không có giá trị

  4. Làm cách nào để thực hiện truy vấn LIKE cho khóa jsonb?

  5. đúng cách để bắt đầu / dừng cơ sở dữ liệu postgres pg_ctl hoặc dịch vụ postgres