PostgreSQL Antipatterns: "рддреНрдпрд╣рд╛рдБ рдПрдЙрдЯрд╛ рдорд╛рддреНрд░ рд╣реБрдиреБрдкрд░реНрдЫ!"

SQL рдорд╛, рддрдкрд╛рдЗрдБ "рдХреЗ" рдкреНрд░рд╛рдкреНрдд рдЧрд░реНрди рдЪрд╛рд╣рд╛рдиреБрд╣реБрдиреНрдЫ рднрдиреЗрд░ рд╡рд░реНрдгрди рдЧрд░реНрдиреБрд╣реБрдиреНрдЫ, "рдХрд╕рд░реА" рдЧрд░реНрдиреБ рд╣реБрдБрджреИрдиред рддреНрдпрд╕рдХрд╛рд░рдг, "рдЬрд╕рд░реА рд╕реБрдирд┐рдиреНрдЫ рдпреЛ рдХрд╕рд░реА рд▓реЗрдЦрд┐рдПрдХреЛ рдЫ" рдХреЛ рд╢реИрд▓реАрдорд╛ SQL рдкреНрд░рд╢реНрдирд╣рд░реВ рд╡рд┐рдХрд╛рд╕ рдЧрд░реНрдиреЗ рд╕рдорд╕реНрдпрд╛рд▓реЗ рдпрд╕рдХреЛ рд╕рдореНрдорд╛рдирдХреЛ рд╕реНрдерд╛рди рд▓рд┐рдиреНрдЫред SQL рдорд╛ рдЕрд╡рд╕реНрдерд╛ рдореВрд▓реНрдпрд╛рдЩреНрдХрди рдХреЛ рд╡рд┐рд╢реЗрд╖рддрд╛рд╣рд░реБ.

рдЖрдЬ, рдЕрддреНрдпрдиреНрдд рд╕рд░рд▓ рдЙрджрд╛рд╣рд░рдгрд╣рд░реВ рдкреНрд░рдпреЛрдЧ рдЧрд░реНрджреИ, рдпреЛ рдкреНрд░рдпреЛрдЧрдХреЛ рд╕рдиреНрджрд░реНрднрдорд╛ рдХреЗ рд╣реБрди рд╕рдХреНрдЫ рд╣реЗрд░реМрдВ GROUP/DISTINCT ╨╕ LIMIT рддрд┐рдиреАрд╣рд░реБрд╕рдБрдЧред

рдпрджрд┐ рддрдкрд╛рдИрд▓реЗ рдЕрдиреБрд░реЛрдзрдорд╛ рд▓реЗрдЦреНрдиреБ рднрдПрдХреЛ рдЫ рднрдиреЗ "рдкрд╣рд┐рд▓реЗ рдпреА рдЯреНрдпрд╛рдмреНрд▓реЗрдЯрд╣рд░реВ рдЬрдбрд╛рди рдЧрд░реНрдиреБрд╣реЛрд╕реН, рд░ рддреНрдпрд╕рдкрдЫрд┐ рд╕рдмреИ рдбреБрдкреНрд▓рд┐рдХреЗрдЯрд╣рд░реВ рдмрд╛рд╣рд┐рд░ рдлрд╛рд▓реНрдиреБрд╣реЛрд╕реН, рддреНрдпрд╣рд╛рдБ рдПрдХ рдорд╛рддреНрд░ рд╣реБрдиреБрдкрд░реНрдЫ рдкреНрд░рддреНрдпреЗрдХ рдХреБрдЮреНрдЬреАрдХреЛ рд▓рд╛рдЧрд┐ рдЙрджрд╛рд╣рд░рдг" - рдпреЛ рдареНрдпрд╛рдХреНрдХреИ рдпреЛ рдХрд╕рд░реА рдХрд╛рдо рдЧрд░реНрдиреЗрдЫ, рднрд▓реЗ рдкрдирд┐ рдЬрдбрд╛рди рдЖрд╡рд╢реНрдпрдХ рдерд┐рдПрдиред

рд░ рдХрд╣рд┐рд▓реЗрдХрд╛рд╣реАрдБ рддрдкрд╛рдИрдВ рднрд╛рдЧреНрдпрд╢рд╛рд▓реА рд╣реБрдиреБрд╣реБрдиреНрдЫ рд░ рдпрд╕рд▓реЗ "рдХреЗрд╡рд▓ рдХрд╛рдо рдЧрд░реНрджрдЫ", рдХрд╣рд┐рд▓реЗрдХрд╛рд╣реАрдБ рдпрд╕рд▓реЗ рдкреНрд░рджрд░реНрд╢рдирдорд╛ рдЕрдкреНрд░рд┐рдп рдкреНрд░рднрд╛рд╡ рдкрд╛рд░реНрдЫ, рд░ рдХрд╣рд┐рд▓реЗрдХрд╛рд╣реАрдБ рдпрд╕рд▓реЗ рд╡рд┐рдХрд╛рд╕рдХрд░реНрддрд╛рдХреЛ рджреГрд╖реНрдЯрд┐рдХреЛрдгрдмрд╛рдЯ рдмрд┐рд▓реНрдХреБрд▓ рдЕрдкреНрд░рддреНрдпрд╛рд╢рд┐рдд рдкреНрд░рднрд╛рд╡рд╣рд░реВ рджрд┐рдиреНрдЫред

PostgreSQL Antipatterns: "рддреНрдпрд╣рд╛рдБ рдПрдЙрдЯрд╛ рдорд╛рддреНрд░ рд╣реБрдиреБрдкрд░реНрдЫ!"
рдард┐рдХ рдЫ, рд╕рд╛рдпрдж рд╢рд╛рдирджрд╛рд░ рд╣реЛрдЗрди, рддрд░ ...

"рдорд┐рдард╛ рдЬреЛрдбреА": JOIN + DISTINCT

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-рд░реЗрдХрд░реНрдбрдмрд╛рдЯ рдиреИ рдХреЗрд╣рд┐ рдЪрд╛рд╣рд┐рдБрджреИрдиред

рдиреЗрд╕реНрдЯреЗрдб рдЕрд╡рд╕реНрдерд┐рдд рдЫ

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: рджреБрд░реНрд▓рдн рд░реЗрдХрд░реНрдб JOIN рдХреЛ рдмреАрдЪрдорд╛ рдкреБрдЧреНрдиреЗрдЫ".

"рдХрд┐рди рдердк рддрд┐рд░реНрдиреЗ": 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

рдпрд╕реНрддреИ рдХреБрд░рд╛рд╣рд░реБ рдлрд░рдХ рдлрд░рдХрдорд╛ рд╣реБрдиреЗ рдЧрд░реНрджрдЫ рд╢реВрдиреНрдпрддрд╛ рдЬрд╛рдБрдЪ рд▓реЗрдмрд▓ рд╡рд╛ CTE рд╣рд░реВ рдЕрдиреБрд░реЛрдз рдмрдвреНрджреИ рдЬрд╛рдБрджрд╛:

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

рд╕рдордЧреНрд░ рдХрд╛рд░реНрдпрд╣рд░реВ (count/min/max/sum/...) рд╕реНрдкрд╖реНрдЯ рд░реВрдкрдорд╛ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдирдЧрд░реА рдкрдирд┐ рд╕рдореНрдкреВрд░реНрдг рд╕реЗрдЯрдорд╛ рд╕рдлрд▓рддрд╛рдкреВрд░реНрд╡рдХ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдЧрд░рд┐рдиреНрдЫ GROUP BYред рдпрд╣рд╛рдБ рд╕рдВрдЧ рдорд╛рддреНрд░ LIMIT рддрд┐рдиреАрд╣рд░реВ рдзреЗрд░реИ рдорд┐рд▓рдирд╕рд╛рд░ рдЫреИрдирдиреНред

рд╡рд┐рдХрд╛рд╕рдХрд░реНрддрд╛рд▓реЗ рд╕реЛрдЪреНрди рд╕рдХреНрдЫ "рдЕрдм, рдпрджрд┐ рддреНрдпрд╣рд╛рдБ рд░реЗрдХрд░реНрдбрд╣рд░реВ рдЫрдиреН рднрдиреЗ, рдорд▓рд╛рдИ 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 рдлрд░рдХ рдорд╛рдирд╣рд░реВ рднреЗрдЯреНрдЯрд╛рдЙрдиреЗ рдмрд┐рддреНрддрд┐рдХреИ.

рднрд╡рд┐рд╖реНрдпрдорд╛ рдХреЗрд╣рд┐ рд╕рдордп, рдпреЛ рд╣реБрди рд╕рдХреНрдЫ рд░ рдПрдХ рдирдпрд╛рдБ рдиреЛрдб рдХреЛ рд▓рд╛рдЧреА рдзрдиреНрдпрд╡рд╛рдж рдХрд╛рдо рдЧрд░реНрдиреЗрдЫ рдЕрдиреБрдХреНрд░рдордгрд┐рдХрд╛ рд╕реНрдХрд┐рдк рд╕реНрдХреНрдпрд╛рдирдЬрд╕рдХреЛ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрдирдХрд╛ рд▓рд╛рдЧрд┐ рдЕрд╣рд┐рд▓реЗ рдХрд╛рдо рднрдЗрд░рд╣реЗрдХреЛ рдЫ рддрд░ рдЕрд╣рд┐рд▓реЗрд╕рдореНрдо рд╣реБрди рд╕рдХреЗрдХреЛ рдЫреИрди ред

рдЕрд╣рд┐рд▓реЗрд╕рдореНрдо рдкрд╣рд┐рд▓реЛ рд╕рдмреИ рд░реЗрдХрд░реНрдбрд╣рд░реВ рдкреБрди: рдкреНрд░рд╛рдкреНрдд рд╣реБрдиреЗрдЫ, рдЕрджреНрд╡рд┐рддреАрдп рдЫрдиреН, рд░ рдЕрдиреБрд░реЛрдз рдЧрд░реЗ рдЕрдиреБрд╕рд╛рд░ рдорд╛рддреНрд░ рдлрд┐рд░реНрддрд╛ рдЧрд░рд┐рдиреЗрдЫред рдпреЛ рд╡рд┐рд╢реЗрд╖ рдЧрд░реА рджреБ: рдЦреА рдЫ рдпрджрд┐ рд╣рд╛рдореА рдХреЗрд╣рд┐ рдЪрд╛рд╣рдиреНрдЫреМрдВ $ рез =ред, рд░ рддрд╛рд▓рд┐рдХрд╛рдорд╛ рд╕рдпреМрдВ рд╣рдЬрд╛рд░реМрдВ рд░реЗрдХрд░реНрдбрд╣рд░реВ рдЫрдиреН ...

рд╡реНрдпрд░реНрдердорд╛ рджреБрдЦреА рдирд╣реБрдирдХреЛ рд▓рд╛рдЧрд┐, рд╣рд╛рдореА рдкреБрдирд░рд╛рд╡рд░реНрддреА рдХреНрд╡реЗрд░реА рдкреНрд░рдпреЛрдЧ рдЧрд░реНрдиреЗрдЫреМрдВ PostgreSQL Wiki рдмрд╛рдЯ "рдЧрд░реАрдмрдХрд╛ рд▓рд╛рдЧрд┐ DISTINCT":

PostgreSQL Antipatterns: "рддреНрдпрд╣рд╛рдБ рдПрдЙрдЯрд╛ рдорд╛рддреНрд░ рд╣реБрдиреБрдкрд░реНрдЫ!"

рд╕реНрд░реЛрдд: www.habr.com

рдПрдХ рдЯрд┐рдкреНрдкрдгреА рдердкреНрди