PostgreSQL
 sql >> база данни >  >> RDS >> PostgreSQL

Как лесно и ефективно да правите заявки за вложени релации в SQL?

Както при всяко запитване, най-ефективният метод е „зависи“. Има много променливи в игра - броя на редовете в таблиците, дължините на редовете, дали съществуват индекси, RAM на сървъра и т.н. и т.н.

Най-добрият начин, по който мога да се сетя за справяне с този вид проблем (мислейки за поддържаемост и смел подход към ефективността), е чрез използване на CTE, което ви позволява да създадете временен резултат и да използвате повторно този резултат във вашата заявка. CTE използват ключовата дума WITH и по същество псевдоним на резултат като таблица, така че да можете да се ПРИСЪЕДИНИТЕ към нея няколко пъти:

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)
;

Ползите от това да го правите по този начин са:

  1. Всеки CTE може да се възползва от индекс на съответните JOIN предикати и да върне резултати само за това подмножество по-бързо, вместо плановият инструмент за изпълнение да се опитва да разрешава поредица от сложни предикати
  2. CTE могат да се поддържат индивидуално, което улеснява отстраняването на проблеми с подгрупи
  3. Вие не нарушавате принципа DRY
  4. Ако CTE има стойност извън заявката, можете да го преместите в съхранена процедура и да я препратите вместо това


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Как да получите списъка с функции в базата данни в PostgreSQL заедно с нейните параметри?

  2. JSON външни ключове в PostgreSQL

  3. Импортирайте XML файлове в PostgreSQL

  4. Изберете колони от извикване на функция в ядрото на sqlalchemy

  5. ValueError:Не може да се прехвърли DatetimeIndex към dtype datetime64[us]