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

Làm cách nào để truy vấn đơn giản và hiệu quả cho các mối quan hệ lồng nhau trong SQL?

Như với bất kỳ truy vấn nào, phương pháp hiệu quả nhất là "nó phụ thuộc". Có nhiều biến trong quá trình chơi - số hàng trong bảng, độ dài hàng, chỉ số có tồn tại hay không, RAM trên máy chủ, v.v.

Cách tốt nhất mà tôi có thể nghĩ đến để xử lý loại vấn đề này (khả năng bảo trì suy nghĩ và cách tiếp cận dũng cảm để đạt được hiệu quả) là sử dụng CTE, cho phép bạn tạo một kết quả tạm thời và sử dụng lại kết quả đó trong suốt truy vấn của bạn. CTE sử dụng từ khóa WITH và về cơ bản là bí danh của một kết quả dưới dạng bảng, do đó bạn có thể THAM GIA với nó nhiều lần:

WITH user_memberships AS (
    SELECT *
    FROM memberships
    WHERE user_id = ${id}
), user_apps AS (
    SELECT *
    FROM apps
    INNER JOIN user_memberships
        ON user_memberships.team_id = apps.team_id
), user_collections AS (
    SELECT *
    FROM collections
    INNER JOIN user_memberships
        ON user_memberships.team_id = collections.team_id
), user_webhooks AS (
    SELECT *
    FROM webhooks
    LEFT OUTER JOIN user_collections ON user_collections.id = webhooks.collection_id
    INNER JOIN user_memberships
        ON user_memberships.team_id = webhooks.team_id
        OR user_memberships.team_id = user_collections.team_id
)

SELECT events.* 
FROM events
WHERE app_id IN (SELECT id FROM user_apps)
OR collection_id IN (SELECT id FROM user_collections)
OR membership_id IN (SELECT id FROM user_memberships)
OR team_id IN (SELECT team_id FROM user_memberships)
OR user_id = ${id}
OR webhook_id IN (SELECT id FROM user_webhooks)
;

Lợi ích của việc làm theo cách này là:

  1. Mỗi CTE có thể tận dụng lợi thế của một chỉ mục trên các vị từ JOIN thích hợp và trả về kết quả chỉ cho tập con đó nhanh hơn, thay vì để người lập kế hoạch thực thi cố gắng giải quyết một loạt các vị từ phức tạp
  2. Các CTE có thể được duy trì riêng lẻ, giúp khắc phục sự cố với các tập hợp con dễ dàng hơn
  3. Bạn không vi phạm nguyên tắc KHÔ
  4. Nếu CTE có giá trị bên ngoài truy vấn, bạn có thể di chuyển nó vào một thủ tục được lưu trữ và tham chiếu để thay thế


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. CHỌN hoặc CHÈN trong một hàm có khuynh hướng gặp phải các điều kiện về chủng tộc không?

  2. Nhận Mã thông báo truy cập cho kết nối với PostgreSQL trong Azure Functions

  3. Postgres / JSON - cập nhật tất cả các phần tử mảng

  4. @T sẵn có (spring-data-react-mongodb) tương đương trong spring-data-r2dbc

  5. Số lượng hàng truy vấn được phân tách theo phạm vi ngày