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

Xóa bằng CTE chậm hơn so với sử dụng bảng tạm trong Postgres

CTE chậm hơn vì nó phải được thực thi không thay đổi (thông qua quét CTE).

TFM (phần 7.8.2) nêu rõ: Các câu lệnh sửa đổi dữ liệu trong WITH được thực thi chính xác một lần và luôn hoàn thành, không phụ thuộc vào việc truy vấn chính có đọc tất cả (hoặc thực sự là bất kỳ) kết quả đầu ra của chúng hay không. chỉ được thực hiện khi truy vấn chính yêu cầu đầu ra của nó.

Do đó, nó là một rào cản tối ưu hóa ; đối với trình tối ưu hóa, việc tháo dỡ CTE không được phép, ngay cả khi nó sẽ dẫn đến một kế hoạch thông minh hơn với cùng kết quả.

Tuy nhiên, giải pháp CTE có thể được cấu trúc lại thành một truy vấn con được kết hợp (tương tự như bảng tạm thời trong câu hỏi). Trong postgres, một truy vấn con được kết hợp thường nhanh hơn so với biến thể EXISTS (), ngày nay.

DELETE FROM customer del
USING ( SELECT id
        , row_number() over(partition by uuid order by created_date desc)
                 as rn
        FROM customer
        ) sub
WHERE sub.id = del.id
AND sub.rn > 1
        ;

Một cách khác là sử dụng TEMP VIEW . Đây là về mặt cú pháp tương đương với temp table trường hợp, nhưng về mặt ngữ nghĩa tương đương với biểu mẫu truy vấn con đã kết hợp (chúng mang lại chính xác cùng một kế hoạch truy vấn, ít nhất là trong trường hợp này). Điều này là do trình tối ưu hóa của Postgres tháo dỡ chế độ xem và kết hợp nó với truy vấn chính ( kéo lên ). Bạn có thể thấy một view như một loại macro trong PG.

CREATE TEMP VIEW targets
AS SELECT id
        , row_number() over(partition by uuid ORDER BY created_date DESC) AS rn
FROM customer;

EXPLAIN
DELETE FROM customer
WHERE id IN ( SELECT id
            FROM targets
            WHERE rn > 1
        );

[CẬP NHẬT:Tôi đã nhầm về việc các CTE cần phải luôn được thực thi để hoàn thành, đây chỉ là trường hợp đối với các CTE sửa đổi dữ liệu]



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Ghi vào tệp từ RAISE NOTICE trong postgresql

  2. PostgreSQL qua SSH Tunnel

  3. Cách tạo API đồ thị không máy chủ cho MySQL, Postgres và Aurora

  4. Cách ánh xạ org.postgresql.geometric.PGpoint sang Loại ngủ đông

  5. Làm cách nào để tạo tiện ích mở rộng postgres bên trong vùng chứa?