PostgreSQL Antipatterns: "เบ•เป‰เบญเบ‡เบกเบตเบญเบฑเบ™เบ”เบฝเบงเป€เบ—เบปเปˆเบฒเบ™เบฑเป‰เบ™!"

เปƒเบ™ SQL, เบ—เปˆเบฒเบ™เบญเบฐเบ—เบดเบšเบฒเบ "เบชเบดเปˆเบ‡เบ—เบตเปˆ" เบ—เปˆเบฒเบ™เบ•เป‰เบญเบ‡เบเบฒเบ™เบ—เบตเปˆเบˆเบฐเบšเบฑเบ™เบฅเบธ, เบšเปเปˆเปเบกเปˆเบ™ "เบงเบดเบ—เบตเบเบฒเบ™" เบกเบฑเบ™เบ„เบงเบ™เบˆเบฐเบ–เบทเบเบ›เบฐเบ•เบดเบšเบฑเบ”. เบ”เบฑเปˆเบ‡เบ™เบฑเป‰เบ™, เบšเบฑเบ™เบซเบฒเบ‚เบญเบ‡เบเบฒเบ™เบžเบฑเบ”เบ—เบฐเบ™เบฒเปเบšเบšเบชเบญเบšเบ–เบฒเบก SQL เปƒเบ™เปเบšเบšเบ‚เบญเบ‡ "เบเป‰เบญเบ™เบงเปˆเบฒเบกเบฑเบ™เป„เบ”เป‰เบเบดเบ™เปเบกเปˆเบ™เบงเบดเบ—เบตเบ—เบตเปˆเบกเบฑเบ™เบ–เบทเบเบ‚เบฝเบ™" เปƒเบŠเป‰เป€เบงเบฅเบฒเป€เบ›เบฑเบ™เบเบฝเบ”, เบžเป‰เบญเบกเบเบฑเบš. เบฅเบฑเบเบชเบฐเบ™เบฐเบ‚เบญเบ‡เบเบฒเบ™เบ„เบดเบ”เป„เบฅเปˆเป€เบ‡เบทเปˆเบญเบ™เป„เบ‚เปƒเบ™ SQL.

เปƒเบ™เบกเบทเป‰เบ™เบตเป‰, เบเบฒเบ™เบ™เปเบฒเปƒเบŠเป‰เบ•เบปเบงเบขเปˆเบฒเบ‡เบ—เบตเปˆเบ‡เปˆเบฒเบเบ”เบฒเบเบ—เบตเปˆเบชเบธเบ”, เปƒเบซเป‰เป€เบšเบดเปˆเบ‡เบชเบดเปˆเบ‡เบ—เบตเปˆเบ™เบตเป‰เบชเบฒเบกเบฒเบ”เบ™เปเบฒเป„เบ›เบชเบนเปˆเบเบฒเบ™เปƒเบ™เบชเบฐเบžเบฒเบšเบเบฒเบ™เบ‚เบญเบ‡เบเบฒเบ™เบ™เปเบฒเปƒเบŠเป‰ GROUP/DISTINCT ะธ LIMIT เบเบฑเบšโ€‹เบžเบงเบโ€‹เป€เบ‚เบปเบฒ.

เปƒเบ™เบ›เบฑเบ”เบˆเบธเบšเบฑเบ™, เบ–เป‰เบฒเบ—เปˆเบฒเบ™เบ‚เบฝเบ™เปƒเบ™เบ„เปเบฒเบฎเป‰เบญเบ‡เบ‚เป "เบ—เปเบฒเบญเบดเบ”เป€เบŠเบทเปˆเบญเบกเบ•เปเปˆเป€เบ„เบทเปˆเบญเบ‡เบซเบกเบฒเบเป€เบซเบผเบปเปˆเบฒเบ™เบตเป‰, เปเบฅเบฐเบซเบผเบฑเบ‡เบˆเบฒเบเบ™เบฑเป‰เบ™เบ–เบดเป‰เบกเบชเบดเปˆเบ‡เบ—เบตเปˆเบŠเป‰เปเบฒเบเบฑเบ™เบ—เบฑเบ‡เบซเบกเบปเบ”, เบ„เบงเบ™เบกเบตเบžเบฝเบ‡เบญเบฑเบ™เบ”เบฝเบงเป€เบ—เบปเปˆเบฒเบ™เบฑเป‰เบ™ เบ•เบปเบงเบขเปˆเบฒเบ‡เบชเปเบฒเบฅเบฑเบšเปเบ•เปˆเบฅเบฐเบเบฐเปเบˆ" - เบ™เบตเป‰เปเบกเปˆเบ™เบงเบดเบ—เบตเบ—เบตเปˆเบกเบฑเบ™เบˆเบฐเป€เบฎเบฑเบ”เบงเบฝเบ, เป€เบ–เบดเบ‡เปเบกเปˆเบ™เบงเปˆเบฒเบเบฒเบ™เป€เบŠเบทเปˆเบญเบกเบ•เปเปˆเบšเปเปˆเบˆเปเบฒเป€เบ›เบฑเบ™เบ—เบฑเบ‡เบซเบกเบปเบ”.

เปเบฅเบฐเบšเบฒเบ‡เบ„เบฑเป‰เบ‡เป€เบˆเบปเป‰เบฒเป‚เบŠเบเบ”เบตเปเบฅเบฐเบกเบฑเบ™ "เบžเบฝเบ‡เปเบ•เปˆเป€เบฎเบฑเบ”เบงเบฝเบ", เบšเบฒเบ‡เบ„เบฑเป‰เบ‡เบกเบฑเบ™เบกเบตเบœเบปเบ™เบเบฐเบ—เบปเบšเบ—เบตเปˆเบšเปเปˆเบ”เบตเบ•เปเปˆเบเบฒเบ™เบ›เบฐเบ•เบดเบšเบฑเบ”, เปเบฅเบฐเบšเบฒเบ‡เบ„เบฑเป‰เบ‡เบกเบฑเบ™เบเปเปˆเปƒเบซเป‰เบœเบปเบ™เบเบฐเบ—เบปเบšเบ—เบตเปˆเบšเปเปˆเบ„เบฒเบ”เบ„เบดเบ”เบขเปˆเบฒเบ‡เบชเบปเบกเบšเบนเบ™เบˆเบฒเบเบ—เบฑเบ”เบชเบฐเบ™เบฐเบ‚เบญเบ‡เบœเบนเป‰เบžเบฑเบ”เบ—เบฐเบ™เบฒ.

PostgreSQL Antipatterns: "เบ•เป‰เบญเบ‡เบกเบตเบญเบฑเบ™เบ”เบฝเบงเป€เบ—เบปเปˆเบฒเบ™เบฑเป‰เบ™!"
เบ”เบต, เบญเบฒเบ”เบˆเบฐเบšเปเปˆเบ›เบฐเบ—เบฑเบšเปƒเบˆเบซเบผเบฒเบ, เปเบ•เปˆ ...

โ€œเบ„เบนเปˆเบฎเบฑเบโ€: เป€เบ‚เบปเป‰เบฒเบฎเปˆเบงเบก + เบ„เบงเบฒเบกเปเบ•เบเบ•เปˆเบฒเบ‡

SELECT DISTINCT
  X.*
FROM
  X
JOIN
  Y
    ON Y.fk = X.pk
WHERE
  Y.bool_condition;

เบกเบฑเบ™เบˆเบฐเปเบˆเป‰เบ‡เบงเปˆเบฒเบžเบงเบเป€เบ‚เบปเบฒเบ•เป‰เบญเบ‡เบเบฒเบ™เบซเบเบฑเบ‡ เป€เบฅเบทเบญเบเบšเบฑเบ™เบ—เบถเบ X เบ—เบตเปˆเบกเบตเบšเบฑเบ™เบ—เบถเบเปƒเบ™ Y เบ—เบตเปˆเบเปˆเบฝเบงเบ‚เป‰เบญเบ‡เบเบฑเบšเป€เบ‡เบทเปˆเบญเบ™เป„เบ‚เบ—เบตเปˆเบชเปเบฒเป€เบฅเบฑเบ”. เบ‚เบฝเบ™เบ„เปเบฒเบฎเป‰เบญเบ‡เบ‚เปเบœเปˆเบฒเบ™ JOIN โ€” เป„เบ”เป‰โ€‹เบฎเบฑเบšโ€‹เบšเบฒเบ‡โ€‹เบ„เปˆเบฒ pk เบซเบผเบฒเบโ€‹เบ„เบฑเป‰เบ‡ (เปเบ™เปˆโ€‹เบ™เบญเบ™โ€‹เบงเปˆเบฒโ€‹เบˆเปเบฒโ€‹เบ™เบงเบ™โ€‹เบ—เบตเปˆโ€‹เป€เบซเบกเบฒเบฐโ€‹เบชเบปเบกโ€‹เบ—เบตเปˆโ€‹เบกเบตโ€‹เบขเบนเปˆโ€‹เปƒเบ™ Yโ€‹)โ€‹. เบงเบดเบ—เบตเบเบฒเบ™เป€เบญเบปเบฒเบญเบญเบ? เปเบ™เปˆเบ™เบญเบ™ DISTINCT!

เบกเบฑเบ™เป‚เบ”เบเบชเบฐเป€เบžเบฒเบฐเปเบกเปˆเบ™ "เบ„เบงเบฒเบกเบžเปเปƒเบˆ" เป€เบกเบทเปˆเบญเปเบ•เปˆเบฅเบฐเบšเบฑเบ™เบ—เบถเบ X เบกเบตเบซเบผเบฒเบเบฎเป‰เบญเบเบšเบฑเบ™เบ—เบถเบ Y เบ—เบตเปˆเบเปˆเบฝเบงเบ‚เป‰เบญเบ‡, เปเบฅเบฐเบซเบผเบฑเบ‡เบˆเบฒเบเบ™เบฑเป‰เบ™เบชเบดเปˆเบ‡เบ—เบตเปˆเบŠเป‰เปเบฒเบเบฑเบ™เป„เบ”เป‰เบ–เบทเบเป‚เบเบเบเป‰เบฒเบเบญเบญเบเบขเปˆเบฒเบ‡เบเป‰เบฒเบซเบฒเบ™ ...

PostgreSQL Antipatterns: "เบ•เป‰เบญเบ‡เบกเบตเบญเบฑเบ™เบ”เบฝเบงเป€เบ—เบปเปˆเบฒเบ™เบฑเป‰เบ™!"

เปเบเป‰เป„เบ‚เปเบ™เบงเปƒเบ”? เป€เบžเบทเปˆเบญเป€เบฅเบตเปˆเบกเบ•เบปเป‰เบ™เบ”เป‰เบงเบ, เบฎเบฑเบšเบฎเบนเป‰เบงเปˆเบฒเบšเบฑเบ™เบซเบฒเบชเบฒเบกเบฒเบ”เปเบเป‰เป„เบ‚เป„เบ”เป‰ "เป€เบฅเบทเบญเบเบšเบฑเบ™เบ—เบถเบ X เบชเปเบฒเบฅเบฑเบšเบ—เบตเปˆ Y เบกเบตเบขเปˆเบฒเบ‡เบซเบ™เป‰เบญเบเบซเบ™เบถเปˆเบ‡เบ—เบตเปˆเบเปˆเบฝเบงเบ‚เป‰เบญเบ‡เบเบฑเบšเป€เบ‡เบทเปˆเบญเบ™เป„เบ‚เบ—เบตเปˆเบชเปเบฒเป€เบฅเบฑเบ”" - เบซเบผเบฑเบ‡เบˆเบฒเบเบ—เบตเปˆเบ—เบฑเบ‡เบซเบกเบปเบ”, เบžเบงเบเป€เบฎเบปเบฒเบšเปเปˆเบ•เป‰เบญเบ‡เบเบฒเบ™เบซเบเบฑเบ‡เบˆเบฒเบ Y-record เบ•เบปเบงเบ‚เบญเบ‡เบกเบฑเบ™เป€เบญเบ‡.

Nested เบกเบตเบขเบนเปˆ

SELECT
  *
FROM
  X
WHERE
  EXISTS(
    SELECT
      NULL
    FROM
      Y
    WHERE
      fk = X.pk AND
      bool_condition
    LIMIT 1
  );

เบšเบฒเบ‡เบชเบฐเบšเบฑเบšเบ‚เบญเบ‡ PostgreSQL เป€เบ‚เบปเป‰เบฒเปƒเบˆเบงเปˆเบฒเปƒเบ™ EXISTS เบกเบฑเบ™เบžเบฝเบ‡เบžเปเบ—เบตเปˆเบˆเบฐเบŠเบญเบเบซเบฒเบฅเบฒเบเบเบฒเบ™เบ—เปเบฒเบญเบดเบ”เบ—เบตเปˆเป€เบเบตเบ”เบ‚เบทเป‰เบ™, เบฎเบธเปˆเบ™เป€เบเบปเปˆเบฒเบšเปเปˆเป„เบ”เป‰. เบชเบฐเบ™เบฑเป‰เบ™เบ‚เป‰เบฒเบžเบฐเป€เบˆเบปเป‰เบฒเบกเบฑเบเบŠเบตเป‰เบšเบญเบเบชเบฐเป€เปเบต LIMIT 1 เบžเบฒเบเปƒเบ™ EXISTS.

เป€เบ‚เบปเป‰เบฒเบฎเปˆเบงเบกเบ‚เป‰เบฒเบ‡เบ„เบฝเบ‡

SELECT
  X.*
FROM
  X
, LATERAL (
    SELECT
      Y.*
    FROM
      Y
    WHERE
      fk = X.pk AND
      bool_condition
    LIMIT 1
  ) Y
WHERE
  Y IS DISTINCT FROM NULL;

เบ—เบฒเบ‡เป€เบฅเบทเบญเบเบ”เบฝเบงเบเบฑเบ™เบญเบฐเบ™เบธเบเบฒเบ”เปƒเบซเป‰, เบ–เป‰เบฒเบˆเปเบฒเป€เบ›เบฑเบ™, เบเบฑเบšเบ„เบทเบ™เบšเบฒเบ‡เบ‚เปเป‰เบกเบนเบ™เบˆเบฒเบเบšเบฑเบ™เบ—เบถเบ Y เบ—เบตเปˆเบเปˆเบฝเบงเบ‚เป‰เบญเบ‡เบ—เบตเปˆเบžเบปเบšเป€เบซเบฑเบ™. เบ—เบฒเบ‡เป€เบฅเบทเบญเบเบ—เบตเปˆเบ„เป‰เบฒเบเบ„เบทเบเบฑเบ™เปเบกเปˆเบ™เบชเบปเบ™เบ—เบฐเบ™เบฒเปƒเบ™เบšเบปเบ”เบ„เบงเบฒเบก "PostgreSQL Antipatterns: เบšเบฑเบ™เบ—เบถเบเบ—เบตเปˆเบซเบฒเบเบฒเบเบˆเบฐเบกเบฒเบฎเบญเบ”เบเบฒเบ‡เบ‚เบญเบ‡เบเบฒเบ™เป€เบ‚เบปเป‰เบฒเบฎเปˆเบงเบก".

โ€œเป€เบ›เบฑเบ™เบซเบเบฑเบ‡เบ•เป‰เบญเบ‡เบˆเปˆเบฒเบเบซเบผเบฒเบโ€: DISTINCT [ON] + LIMIT 1

เบœเบปเบ™เบ›เบฐเป‚เบซเบเบ”เป€เบžเบตเปˆเบกเป€เบ•เบตเบกเบ‚เบญเบ‡เบเบฒเบ™เบซเบฑเบ™เบ›เปˆเบฝเบ™เปเบšเบšเบชเบญเบšเบ–เบฒเบกเบ”เบฑเปˆเบ‡เบเปˆเบฒเบงเปเบกเปˆเบ™เบ„เบงเบฒเบกเบชเบฒเบกเบฒเบ”เปƒเบ™เบเบฒเบ™เบˆเปเบฒเบเบฑเบ”เบเบฒเบ™เบ„เบปเป‰เบ™เบซเบฒเบšเบฑเบ™เบ—เบถเบเป„เบ”เป‰เบขเปˆเบฒเบ‡เบ‡เปˆเบฒเบเบ”เบฒเบเบ–เป‰เบฒเบ•เป‰เบญเบ‡เบเบฒเบ™เบžเบฝเบ‡เปเบ•เปˆเบซเบ™เบถเปˆเบ‡เบซเบผเบทเบชเบญเบ‡เบชเบฒเบกเบญเบฑเบ™, เป€เบŠเบฑเปˆเบ™เบ”เบฝเบงเบเบฑเบšเบเปเบฅเบฐเบ™เบตเบ•เปเปˆเป„เบ›เบ™เบตเป‰:

SELECT DISTINCT ON(X.pk)
  *
FROM
  X
JOIN
  Y
    ON Y.fk = X.pk
LIMIT 1;

เปƒเบ™เบ›เบฑเบ”เบˆเบธเบšเบฑเบ™เบžเบงเบเป€เบฎเบปเบฒเป„เบ”เป‰เบญเปˆเบฒเบ™เบ„เปเบฒเบฎเป‰เบญเบ‡เบ‚เปเปเบฅเบฐเบžเบฐเบเบฒเบเบฒเบกเป€เบ‚เบปเป‰เบฒเปƒเบˆเบชเบดเปˆเบ‡เบ—เบตเปˆ DBMS เบชเบฐเป€เบซเบ™เบตเปƒเบซเป‰เป€เบฎเบฑเบ”:

  • เบเบฒเบ™โ€‹เป€เบŠเบทเปˆเบญเบกโ€‹เบ•เปเปˆโ€‹เบชเบฑเบ™โ€‹เบเบฒเบ™โ€‹
  • เป€เบ›เบฑเบ™เป€เบญเบเบฐเบฅเบฑเบเป‚เบ”เบ X.pk
  • เบˆเบฒเบเบฅเบฒเบเบเบฒเบ™เบ—เบตเปˆเบเบฑเบ‡เป€เบซเบผเบทเบญ, เป€เบฅเบทเบญเบเบญเบฑเบ™เปœเบถเปˆเบ‡

เบ”เบฑเปˆเบ‡เบ™เบฑเป‰เบ™เป€เบˆเบปเป‰เบฒเป„เบ”เป‰เบฎเบฑเบšเบซเบเบฑเบ‡? "เบžเบฝเบ‡เปเบ•เปˆเบซเบ™เบถเปˆเบ‡เป€เบ‚เบปเป‰เบฒ" เบˆเบฒเบเบชเบดเปˆเบ‡เบ—เบตเปˆเป€เบ›เบฑเบ™เป€เบญเบเบฐเบฅเบฑเบ - เปเบฅเบฐเบ–เป‰เบฒเบžเบงเบเป€เบฎเบปเบฒเป€เบญเบปเบฒเบญเบฑเบ™เบซเบ™เบถเปˆเบ‡เบ—เบตเปˆเบšเปเปˆเป€เบ›เบฑเบ™เป€เบญเบเบฐเบฅเบฑเบ, เบœเบปเบ™เป„เบ”เป‰เบฎเบฑเบšเบˆเบฐเบ›เปˆเบฝเบ™เปเบ›เบ‡เปเบ™เบงเปƒเบ”? ... "เปเบฅเบฐเบ–เป‰เบฒเบšเปเปˆเบกเบตเบ„เบงเบฒเบกเปเบ•เบเบ•เปˆเบฒเบ‡เบเบฑเบ™, เป€เบ›เบฑเบ™เบซเบเบฑเบ‡เบ•เป‰เบญเบ‡เบˆเปˆเบฒเบเบซเบผเบฒเบ?"

SELECT
  *
FROM
  (
    SELECT
      *
    FROM
      X
    -- ััŽะดะฐ ะผะพะถะฝะพ ะฟะพะดััƒะฝัƒั‚ัŒ ะฟะพะดั…ะพะดัั‰ะธั… ัƒัะปะพะฒะธะน
    LIMIT 1 -- +1 Limit
  ) X
JOIN
  Y
    ON Y.fk = X.pk
LIMIT 1;

เปเบฅเบฐเปเบ—เป‰เบซเบปเบงเบ‚เปเป‰เบ”เบฝเบงเบเบฑเบ™เบเบฑเบš GROUP BY + LIMIT 1.

"เบ‚เป‰เบญเบเบžเบฝเบ‡เปเบ•เปˆเบ•เป‰เบญเบ‡เบ–เบฒเบก": GROUP + LIMIT implicit

เบชเบดเปˆเบ‡เบ—เบตเปˆเบ„เป‰เบฒเบเบ„เบทเบเบฑเบ™เป€เบเบตเบ”เบ‚เบถเป‰เบ™เบขเบนเปˆเปเบ•เบเบ•เปˆเบฒเบ‡เบเบฑเบ™ เบเบฒเบ™เบเบงเบ”เบชเบญเบšเบ„เบงเบฒเบกเบšเปเปˆเบซเบงเปˆเบฒเบ‡เป€เบ›เบปเปˆเบฒ เบชเบฑเบ™เบเบฒเบ™ เบซเบผเบท CTEs เป€เบกเบทเปˆเบญเบเบฒเบ™เบฎเป‰เบญเบ‡เบ‚เปเบ”เบณเป€เบ™เบตเบ™เป„เบ›:

...
CASE
  WHEN (
    SELECT
      count(*)
    FROM
      X
    LIMIT 1
  ) = 0 THEN ...

เบŸเบฑเบ‡เบŠเบฑเบ™เบฅเบงเบก (count/min/max/sum/...) เบ–เบทเบเบ›เบฐเบ•เบดเบšเบฑเบ”เบขเปˆเบฒเบ‡เบชเปเบฒเป€เบฅเบฑเบ”เบœเบปเบ™เปƒเบ™เบŠเบธเบ”เบ—เบฑเบ‡เบซเบกเบปเบ”, เป€เบ–เบดเบ‡เปเบกเปˆเบ™เบงเปˆเบฒเบšเปเปˆเบกเบตเบ„เปเบฒเปเบ™เบฐเบ™เปเบฒเบ—เบตเปˆเบŠเบฑเบ”เป€เบˆเบ™ GROUP BY. เบžเบฝเบ‡เปเบ•เปˆเบเบฑเบš LIMIT เป€เบ‚เบปเบฒเป€เบˆเบปเป‰เบฒเบšเปเปˆเป€เบ›เบฑเบ™เบกเบดเบ”เบซเบผเบฒเบ.

เบ™เบฑเบเบžเบฑเบ”เบ—เบฐเบ™เบฒเบชเบฒเบกเบฒเบ”เบ„เบดเบ”เป„เบ”เป‰ "เบ–เป‰เบฒเบกเบตเบšเบฑเบ™เบ—เบถเบเบขเบนเปˆเบ—เบตเปˆเบ™เบฑเป‰เบ™, เบ‚เป‰เบญเบเบ•เป‰เบญเบ‡เบเบฒเบ™เบšเปเปˆเป€เบเบตเบ™เบ‚เบญเบšเป€เบ‚เบ”เบˆเปเบฒเบเบฑเบ”". เปเบ•เปˆเบขเปˆเบฒเป€เบฎเบฑเบ”เปเบ™เบงเบ™เบฑเป‰เบ™! เป€เบ™เบทเปˆเบญเบ‡เบˆเบฒเบเบงเปˆเบฒเบžเบทเป‰เบ™เบ–เบฒเบ™เบกเบฑเบ™เปเบกเปˆเบ™:

  • เบ™เบฑเบšเบชเบดเปˆเบ‡เบ—เบตเปˆเป€เบ‚เบปเบฒเป€เบˆเบปเป‰เบฒเบ•เป‰เบญเบ‡เบเบฒเบ™ เบญเบตเบ‡โ€‹เบ•เบฒเบกโ€‹เบเบฒเบ™โ€‹เบšเบฑเบ™โ€‹เบ—เบถเบโ€‹เบ—เบฑเบ‡โ€‹เบซเบกเบปเบ”โ€‹
  • เปƒเบซเป‰เบซเบผเบฒเบเป€เบชเบฑเป‰เบ™เป€เบ—เบปเปˆเบฒเบ—เบตเปˆเบžเบงเบเป€เบ‚เบปเบฒเบฎเป‰เบญเบ‡เบ‚เป

เบญเบตเบ‡เบ•เบฒเบกเป€เบ‡เบทเปˆเบญเบ™เป„เบ‚เป€เบ›เบปเป‰เบฒเบซเบกเบฒเบ, เบกเบฑเบ™เป€เบซเบกเบฒเบฐเบชเบปเบกเบ—เบตเปˆเบˆเบฐเป€เบฎเบฑเบ”เปƒเบซเป‰เบซเบ™เบถเปˆเบ‡เปƒเบ™เบเบฒเบ™เบ—เบปเบ”เปเบ—เบ™เบ”เบฑเปˆเบ‡เบ•เปเปˆเป„เบ›เบ™เบตเป‰:

  • (count + LIMIT 1) = 0 เบชเบธเบ” NOT EXISTS(LIMIT 1)
  • (count + LIMIT 1) > 0 เบชเบธเบ” EXISTS(LIMIT 1)
  • count >= N เบชเบธเบ” (SELECT count(*) FROM (... LIMIT N))

โ€œเบซเป‰เบญเบเป€เบ›เบฑเบ™เบเบผเบฒเบกเป€เบ—เบปเปˆเบฒเปƒเบ”โ€: DISTINCT + LIMIT

SELECT DISTINCT
  pk
FROM
  X
LIMIT $1

เบ™เบฑเบเบžเบฑเบ”เบ—เบฐเบ™เบฒเบ—เบตเปˆเบšเปเปˆเบกเบตเป€เบซเบ”เบœเบปเบ™เบญเบฒเบ”เบˆเบฐเป€เบŠเบทเปˆเบญเบขเปˆเบฒเบ‡เบˆเบดเบ‡เปƒเบˆเบงเปˆเบฒเบ„เปเบฒเบฎเป‰เบญเบ‡เบ‚เปเบˆเบฐเบขเบธเบ”เป€เบŠเบปเบฒเบเบฒเบ™เบ›เบฐเบ•เบดเบšเบฑเบ”. เบ—เบฑเบ™เบ—เบตเบ—เบตเปˆเบžเบงเบเป€เบฎเบปเบฒเบŠเบญเบเบซเบฒ $1 เบ‚เบญเบ‡เบ„เปˆเบฒเบ—เบตเปˆเปเบ•เบเบ•เปˆเบฒเบ‡เบเบฑเบ™เบ—เปเบฒเบญเบดเบ”เบ—เบตเปˆเป€เบ‚เบปเป‰เบฒเบกเบฒ.

เบšเบฒเบ‡เบ„เบฑเป‰เบ‡เปƒเบ™เบญเบฐเบ™เบฒเบ„เบปเบ”เบ™เบตเป‰เบญเบฒเบ”เบˆเบฐเปเบฅเบฐเบˆเบฐเป€เบฎเบฑเบ”เบงเบฝเบเบ‚เปเบ‚เบญเบšเปƒเบˆเบเบฑเบš node เปƒเบซเบกเปˆ เบ”เบฑเบ”เบŠเบฐเบ™เบตเบ‚เป‰เบฒเบกเบเบฒเบ™เบชเบฐเปเบเบ™, เบเบฒเบ™โ€‹เบ›เบฐโ€‹เบ•เบดโ€‹เบšเบฑเบ”โ€‹เปƒเบ™โ€‹เบ›เบฑเบ”โ€‹เบˆเบธโ€‹เบšเบฑเบ™โ€‹เปเบกเปˆเบ™โ€‹เป„เบ”เป‰โ€‹เบฎเบฑเบšโ€‹เบเบฒเบ™โ€‹เปเบเป‰โ€‹เป„เบ‚โ€‹, เปเบ•เปˆโ€‹เบเบฑเบ‡โ€‹เบšเปเปˆโ€‹เบ—เบฑเบ™โ€‹เป„เบ”เป‰โ€‹.

เบชเปเบฒเบฅเบฑเบšเปƒเบ™เบ›เบฑเบ”เบˆเบธเบšเบฑเบ™เบ—เปเบฒเบญเบดเบ” เบšเบฑเบ™เบ—เบถเบเบ—เบฑเบ‡เปเบปเบ”เบˆเบฐเบ–เบทเบเบ”เบถเบ‡เบกเบฒ, เป€เบ›เบฑเบ™เป€เบญเบเบฐเบฅเบฑเบ, เปเบฅเบฐเบžเบฝเบ‡เปเบ•เปˆเบˆเบฒเบเบžเบงเบเบกเบฑเบ™เบˆเบฐเบˆเปเบฒเบ™เบงเบ™เบ—เบตเปˆเบฎเป‰เบญเบ‡เบ‚เปเบ„เบทเบ™. เบกเบฑเบ™เป€เบ›เบฑเบ™เบชเบดเปˆเบ‡เบ—เบตเปˆเป‚เบชเบเป€เบชเบปเป‰เบฒเป‚เบ”เบเบชเบฐเป€เบžเบฒเบฐเบ–เป‰เบฒเบžเบงเบเป€เบฎเบปเบฒเบ•เป‰เบญเบ‡เบเบฒเบ™เบšเบฒเบ‡เบชเบดเปˆเบ‡เบšเบฒเบ‡เบขเปˆเบฒเบ‡เป€เบŠเบฑเปˆเบ™: $ 1 = 4, เปเบฅเบฐเบกเบตเบซเบผเบฒเบเบฎเป‰เบญเบเบžเบฑเบ™เบšเบฑเบ™เบ—เบถเบเบขเบนเปˆเปƒเบ™เบ•เบฒเบ•เบฐเบฅเบฒเบ‡ ...

เปƒเบ™เบ„เปเบฒเบชเบฑเปˆเบ‡เบ—เบตเปˆเบˆเบฐเบšเปเปˆเป€เบชเบเปƒเบˆเปƒเบ™ vain, เปƒเบซเป‰เป€เบฎเบปเบฒเปƒเบŠเป‰เบเบฒเบ™เบชเบญเบšเบ–เบฒเบก recursive "DISTINCT เปเบกเปˆเบ™เบชเปเบฒเบฅเบฑเบšเบœเบนเป‰เบ—เบธเบเบเบฒเบ" เบˆเบฒเบ PostgreSQL Wiki:

PostgreSQL Antipatterns: "เบ•เป‰เบญเบ‡เบกเบตเบญเบฑเบ™เบ”เบฝเบงเป€เบ—เบปเปˆเบฒเบ™เบฑเป‰เบ™!"

เปเบซเบผเปˆเบ‡เบ‚เปเป‰เบกเบนเบ™: www.habr.com

เป€เบžเบตเปˆเบกเบ„เบงเบฒเบกเบ„เบดเบ”เป€เบซเบฑเบ™