PostgreSQL Antipatterns: рд╣рд╛рдирд┐рдХрд╛рд░рдХ JOINs рд░ ORs

рдмрдлрд░рд╣рд░реВ рд▓реНрдпрд╛рдЙрдиреЗ рдЕрдкрд░реЗрд╢рдирд╣рд░реВрдмрд╛рдЯ рд╕рд╛рд╡рдзрд╛рди рд░рд╣рдиреБрд╣реЛрд╕реН ...
рдЙрджрд╛рд╣рд░рдгрдХреЛ рд░реВрдкрдорд╛ рдПрдЙрдЯрд╛ рд╕рд╛рдиреЛ рдХреНрд╡реЗрд░реА рдкреНрд░рдпреЛрдЧ рдЧрд░реНрджреИ, PostgreSQL рдорд╛ рдХреНрд╡реЗрд░реАрд╣рд░реВ рдЕрдиреБрдХреВрд▓рди рдЧрд░реНрди рдХреЗрд╣реА рд╡рд┐рд╢реНрд╡рд╡реНрдпрд╛рдкреА рджреГрд╖реНрдЯрд┐рдХреЛрдгрд╣рд░реВ рд╣реЗрд░реМрдВред рддрдкрд╛рдЗрдБ рддрд┐рдиреАрд╣рд░реВрд▓рд╛рдИ рдкреНрд░рдпреЛрдЧ рдЧрд░реНрдиреБрд╣реБрдиреНрдЫ рд╡рд╛ рдирдЧрд░реНрдиреБрд╣реЛрд╕реН рддрдкрд╛рдЗрдБрдорд╛ рдирд┐рд░реНрднрд░ рдЫ, рддрд░ рдпреЛ рддрд┐рдиреАрд╣рд░реВрдХреЛ рдмрд╛рд░реЗрдорд╛ рдЬрд╛рдиреНрди рд▓рд╛рдпрдХ рдЫред

PG рдХреЛ рдХреЗрд╣реА рдкрдЫрд┐рд▓реНрд▓рд╛ рд╕рдВрд╕реНрдХрд░рдгрд╣рд░реВрдорд╛ рдЕрдиреБрд╕реВрдЪрдХ рд╕реНрдорд╛рд░реНрдЯ рд╣реБрдБрджреИ рдЬрд╛рдБрджрд╛ рд╕реНрдерд┐рддрд┐ рдкрд░рд┐рд╡рд░реНрддрди рд╣реБрди рд╕рдХреНрдЫ, рддрд░ 9.4/9.6 рдХреЛ рд▓рд╛рдЧрд┐ рдпреЛ рд▓рдЧрднрдЧ рдЙрд╕реНрддреИ рджреЗрдЦрд┐рдиреНрдЫ, рдпрд╣рд╛рдБ рдЙрджрд╛рд╣рд░рдгрд╣рд░реВрдорд╛ред

рдПрдХ рдзреЗрд░реИ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдЕрдиреБрд░реЛрдз рдЧрд░реМрдВ:

SELECT
  TRUE
FROM
  "╨Ф╨╛╨║╤Г╨╝╨╡╨╜╤В" d
INNER JOIN
  "╨Ф╨╛╨║╤Г╨╝╨╡╨╜╤В╨а╨░╤Б╤И╨╕╤А╨╡╨╜╨╕╨╡" doc_ex
    USING("@╨Ф╨╛╨║╤Г╨╝╨╡╨╜╤В")
INNER JOIN
  "╨в╨╕╨┐╨Ф╨╛╨║╤Г╨╝╨╡╨╜╤В╨░" t_doc ON
    t_doc."@╨в╨╕╨┐╨Ф╨╛╨║╤Г╨╝╨╡╨╜╤В╨░" = d."╨в╨╕╨┐╨Ф╨╛╨║╤Г╨╝╨╡╨╜╤В╨░"
WHERE
  (d."╨Ы╨╕╤Ж╨╛3" = 19091 or d."╨б╨╛╤В╤А╤Г╨┤╨╜╨╕╨║" = 19091) AND
  d."$╨з╨╡╤А╨╜╨╛╨▓╨╕╨║" IS NULL AND
  d."╨г╨┤╨░╨╗╨╡╨╜" IS NOT TRUE AND
  doc_ex."╨б╨╛╤Б╤В╨╛╤П╨╜╨╕╨╡"[1] IS TRUE AND
  t_doc."╨в╨╕╨┐╨Ф╨╛╨║╤Г╨╝╨╡╨╜╤В╨░" = '╨Я╨╗╨░╨╜╨а╨░╨▒╨╛╤В'
LIMIT 1;

рддрд╛рд▓рд┐рдХрд╛ рд░ рдХреНрд╖реЗрддреНрд░ рдирд╛рдо рдмрд╛рд░реЗрдХреНрд╖реЗрддреНрд░ рд░ рддрд╛рд▓рд┐рдХрд╛рд╣рд░реВрдХреЛ "рд░реВрд╕реА" рдирд╛рдорд╣рд░реВ рдлрд░рдХ рд░реВрдкрдорд╛ рд╡реНрдпрд╡рд╣рд╛рд░ рдЧрд░реНрди рд╕рдХрд┐рдиреНрдЫ, рддрд░ рдпреЛ рд╕реНрд╡рд╛рджрдХреЛ рдХреБрд░рд╛ рд╣реЛред рдХрд┐рдирдХрд┐ рддреНрдпреЛ рдпрд╣рд╛рдБ Tensor рдорд╛ рддреНрдпрд╣рд╛рдБ рдХреБрдиреИ рд╡рд┐рджреЗрд╢реА рд╡рд┐рдХрд╛рд╕рдХрд░реНрддрд╛рд╣рд░реВ рдЫреИрдирдиреН, рд░ PostgreSQL рд▓реЗ рд╣рд╛рдореАрд▓рд╛рдИ рд╣рд╛рдЗрд░реЛрдЧреНрд▓рд┐рдлрд╣рд░реВрдорд╛ рдкрдирд┐ рдирд╛рдорд╣рд░реВ рджрд┐рди рдЕрдиреБрдорддрд┐ рджрд┐рдиреНрдЫ, рдпрджрд┐ рддрд┐рдиреАрд╣рд░реВ рдЙрджреНрдзрд░рдгрд╣рд░реВрдорд╛ рд╕рдВрд▓рдЧреНрди, рддреНрдпрд╕рдкрдЫрд┐ рд╣рд╛рдореА рд╡рд╕реНрддреБрд╣рд░реВрдХреЛ рдирд╛рдо рд╕реНрдкрд╖реНрдЯ рд░ рд╕реНрдкрд╖реНрдЯ рд░реВрдкрдорд╛ рд░рд╛рдЦреНрди рд░реБрдЪрд╛рдЙрдБрдЫреМрдВ рддрд╛рдХрд┐ рддреНрдпрд╣рд╛рдБ рдХреБрдиреИ рд╡рд┐рд╕рдВрдЧрддрд┐рд╣рд░реВ рдЫреИрдирдиреНред
рдирддрд┐рдЬрд╛ рдпреЛрдЬрдирд╛ рд╣реЗрд░реМрдВ:
PostgreSQL Antipatterns: рд╣рд╛рдирд┐рдХрд╛рд░рдХ JOINs рд░ ORs
[explan.tensor.ru рдорд╛ рд╣реЗрд░реНрдиреБрд╣реЛрд╕реН]

144ms рд░ рд▓рдЧрднрдЧ 53K рдмрдлрд░рд╣рд░реВ - рдЕрд░реНрдерд╛рддреН, 400MB рднрдиреНрджрд╛ рдмрдвреА рдбрд╛рдЯрд╛! рд░ рд╣рд╛рдореА рднрд╛рдЧреНрдпрд╢рд╛рд▓реА рд╣реБрдиреЗрдЫреМрдВ рдпрджрд┐ рддреА рд╕рдмреИ рд╣рд╛рдореНрд░реЛ рдЕрдиреБрд░реЛрдзрдХреЛ рд╕рдордпрдорд╛ рдХреНрдпрд╛рд╕рдорд╛ рдЫрдиреН, рдЕрдиреНрдпрдерд╛ рдбрд┐рд╕реНрдХрдмрд╛рдЯ рдкрдвреНрджрд╛ рдпрд╕рд▓реЗ рдзреЗрд░реИ рдкрдЯрдХ рд▓рд╛рдореЛ рд╕рдордп рд▓рд┐рдиреЗрдЫред

рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо рд╕рдмреИрднрдиреНрджрд╛ рдорд╣рддреНрддреНрд╡рдкреВрд░реНрдг рдЫ!

рдХреБрдиреИ рдкрдирд┐ рдЕрдиреБрд░реЛрдзрд▓рд╛рдИ рдЕрдкреНрдЯрд┐рдорд╛рдЗрдЬ рдЧрд░реНрдирдХреЛ рд▓рд╛рдЧрд┐, рддрдкрд╛рдИрдВрд▓реЗ рдкрд╣рд┐рд▓реЗ рдпреЛ рдХреЗ рдЧрд░реНрдиреБрдкрд░реНрдЫ рднрдиреЗрд░ рдмреБрдЭреНрдиреБрдкрд░реНрдЫред
рдбрд╛рдЯрд╛рдмреЗрд╕ рд╕рдВрд░рдЪрдирд╛рдХреЛ рд╡рд┐рдХрд╛рд╕рд▓рд╛рдИ рдЕрд╣рд┐рд▓реЗрдХреЛ рд▓рд╛рдЧрд┐ рдпрд╕ рд▓реЗрдЦрдХреЛ рджрд╛рдпрд░рд╛ рдмрд╛рд╣рд┐рд░ рдЫреЛрдбреМрдВ, рд░ рд╣рд╛рдореА рдЕрдкреЗрдХреНрд╖рд╛рдХреГрдд "рд╕рд╕реНрддреЛ" рдЧрд░реНрди рд╕рдХреНрдЫреМрдВ рднрдиреНрдиреЗ рдХреБрд░рд╛рдорд╛ рд╕рд╣рдордд рдЫреМрдВред рдЕрдиреБрд░реЛрдз рдкреБрди: рд▓реЗрдЦреНрдиреБрд╣реЛрд╕реН рд░/рд╡рд╛ рд╣рд╛рдореАрд▓рд╛рдИ рдЪрд╛рд╣рд┐рдиреЗ рдХреЗрд╣реА рдЪреАрдЬрд╣рд░реВрдХреЛ рдЖрдзрд╛рд░рдорд╛ рд░реЛрд▓ рдЧрд░реНрдиреБрд╣реЛрд╕реН рд╕реВрдЪрдХрд╛рдВрдХ.

рддреНрдпрд╕реИрд▓реЗ рдЕрдиреБрд░реЛрдз:
- рдХрдореНрддрд┐рдорд╛ рдХреЗрд╣реА рдХрд╛рдЧрдЬрд╛рддрдХреЛ рдЕрд╕реНрддрд┐рддреНрд╡ рдЬрд╛рдБрдЪ рдЧрд░реНрджрдЫ
- рд╣рд╛рдореАрд▓рд╛рдИ рдЪрд╛рд╣рд┐рдиреЗ рдЕрд╡рд╕реНрдерд╛рдорд╛ рд░ рдПрдХ рдирд┐рд╢реНрдЪрд┐рдд рдкреНрд░рдХрд╛рд░рдХреЛ
- рдЬрд╣рд╛рдБ рд▓реЗрдЦрдХ рд╡рд╛ рдХрд▓рд╛рдХрд╛рд░ рд╣рд╛рдореАрд▓рд╛рдИ рдЪрд╛рд╣рд┐рдиреЗ рдХрд░реНрдордЪрд╛рд░реА рд╣реЛ

JOIN + LIMIT рез

рдзреЗрд░реИ рдкрдЯрдХ рдпреЛ рдПрдХ рд╡рд┐рдХрд╛рд╕рдХрд░реНрддрд╛ рдХреЛ рд▓рд╛рдЧреА рдПрдХ рдХреНрд╡реЗрд░реА рд▓реЗрдЦреНрди рдХреЛ рд▓рд╛рдЧреА рд╕рдЬрд┐рд▓реЛ рдЫ рдЬрд╣рд╛рдБ рддрд╛рд▓рд┐рдХрд╛рд╣рд░реБ рдХреЛ рдПрдХ рдареВрд▓реЛ рд╕рдВрдЦреНрдпрд╛ рдкрд╣рд┐рд▓реЗ рдЬреЛрдбрд┐рдПрдХреЛ рдЫ, рд░ рддреНрдпрд╕рдкрдЫрд┐ рдпреЛ рд╕рдореНрдкреВрд░реНрдг рд╕реЗрдЯрдмрд╛рдЯ рдХреЗрд╡рд▓ рдПрдХ рд░реЗрдХрд░реНрдб рд░рд╣рдиреНрдЫред рддрд░ рд╡рд┐рдХрд╛рд╕рдХрд░реНрддрд╛рдХреЛ рд▓рд╛рдЧрд┐ рд╕рдЬрд┐рд▓реЛ рднрдиреЗрдХреЛ рдбрд╛рдЯрд╛рдмреЗрд╕рдХреЛ рд▓рд╛рдЧрд┐ рдмрдвреА рдкреНрд░рднрд╛рд╡рдХрд╛рд░реА рд╣реЛрдЗрдиред
рд╣рд╛рдореНрд░реЛ рдЕрд╡рд╕реНрдерд╛рдорд╛ рддреНрдпрд╣рд╛рдБ рдХреЗрд╡рд▓ 3 рддрд╛рд▓рд┐рдХрд╛рд╣рд░реВ рдерд┐рдП - рд░ рдкреНрд░рднрд╛рд╡ рдХреЗ рд╣реЛ ...

рдкрд╣рд┐рд▓реЗ "рдХрд╛рдЧрдЬрд╛рдд рдкреНрд░рдХрд╛рд░" рддрд╛рд▓рд┐рдХрд╛рдХреЛ рдЬрдбрд╛рдирдмрд╛рдЯ рдЫреБрдЯрдХрд╛рд░рд╛ рдкрд╛рдЙрдиреБрд╣реЛрд╕реН, рд░ рдПрдХреИ рд╕рдордпрдорд╛ рдбрд╛рдЯрд╛рдмреЗрд╕рд▓рд╛рдИ рдмрддрд╛рдЙрдиреБрд╣реЛрд╕реНред рд╣рд╛рдореНрд░реЛ рдкреНрд░рдХрд╛рд░ рд░реЗрдХрд░реНрдб рдЕрджреНрд╡рд┐рддреАрдп рдЫ (рд╣рд╛рдореАрд▓рд╛рдИ рдпреЛ рдерд╛рд╣рд╛ рдЫ, рддрд░ рдЕрдиреБрд╕реВрдЪрдХрд▓рд╛рдИ рдЕрдЭреИ рдерд╛рд╣рд╛ рдЫреИрди):

WITH T AS (
  SELECT
    "@╨в╨╕╨┐╨Ф╨╛╨║╤Г╨╝╨╡╨╜╤В╨░"
  FROM
    "╨в╨╕╨┐╨Ф╨╛╨║╤Г╨╝╨╡╨╜╤В╨░"
  WHERE
    "╨в╨╕╨┐╨Ф╨╛╨║╤Г╨╝╨╡╨╜╤В╨░" = '╨Я╨╗╨░╨╜╨а╨░╨▒╨╛╤В'
  LIMIT 1
)
...
WHERE
  d."╨в╨╕╨┐╨Ф╨╛╨║╤Г╨╝╨╡╨╜╤В╨░" = (TABLE T)
...

рд╣реЛ, рдпрджрд┐ рддрд╛рд▓рд┐рдХрд╛/CTE рдорд╛ рдПрдЙрдЯреИ рд░реЗрдХрд░реНрдбрдХреЛ рдПрдЙрдЯреИ рдлрд┐рд▓реНрдб рд╕рдорд╛рд╡реЗрд╢ рдЫ рднрдиреЗ, рддреНрдпрд╕рдкрдЫрд┐ PG рдорд╛ рддрдкрд╛рдИрд▓реЗ рдпрд╕рд░реА рд▓реЗрдЦреНрди рд╕рдХреНрдиреБрд╣реБрдиреНрдЫ, рдпрд╕рдХреЛ рд╕рдЯреНрдЯрд╛

d."╨в╨╕╨┐╨Ф╨╛╨║╤Г╨╝╨╡╨╜╤В╨░" = (SELECT "@╨в╨╕╨┐╨Ф╨╛╨║╤Г╨╝╨╡╨╜╤В╨░" FROM T LIMIT 1)

PostgreSQL рдкреНрд░рд╢реНрдирд╣рд░реВрдорд╛ рдЕрд▓реНрдЫреА рдореВрд▓реНрдпрд╛рдЩреНрдХрди

BitmapOr рдмрдирд╛рдо UNION

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

(
  SELECT
    ...
  LIMIT 1
)
UNION ALL
(
  SELECT
    ...
  LIMIT 1
)
LIMIT 1

"рдмрд╛рд╣реНрдп" LIMIT 1 рд▓реЗ рдкрд╣рд┐рд▓реЛ рд░реЗрдХрд░реНрдб рдлреЗрд▓рд╛ рдкрд░реНрджрд╛ рдЦреЛрдЬреА рд╕рдорд╛рдкреНрдд рд╣реБрдиреНрдЫ рднрдиреНрдиреЗ рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдЧрд░реНрджрдЫред рд░ рдпрджрд┐ рдпреЛ рдкрд╣рд┐рд▓реЗ рдиреИ рдкрд╣рд┐рд▓реЛ рдмреНрд▓рдХрдорд╛ рдлреЗрд▓рд╛ рдкрд░реНрдпреЛ рднрдиреЗ, рджреЛрд╕реНрд░реЛ рдмреНрд▓рдХ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рд╣реБрдиреЗрдЫреИрди (рдХрд╣рд┐рд▓реНрдпреИ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рднрдПрди рдХреЛ рд╕рдиреНрджрд░реНрднрдорд╛)ред

"рдХреЗрд╕ рдЕрдиреНрддрд░реНрдЧрдд рдХрдард┐рди рдкрд░рд┐рд╕реНрдерд┐рддрд┐рд╣рд░реВ рд▓реБрдХрд╛рдЙрдБрджреИ"

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

SELECT
  ...
FROM
  "╨Ф╨╛╨║╤Г╨╝╨╡╨╜╤В" d
WHERE
  ... /*index cond*/ AND
  CASE
    WHEN "$╨з╨╡╤А╨╜╨╛╨▓╨╕╨║" IS NULL AND "╨г╨┤╨░╨╗╨╡╨╜" IS NOT TRUE THEN (
      SELECT
        "╨б╨╛╤Б╤В╨╛╤П╨╜╨╕╨╡"[1] IS TRUE
      FROM
        "╨Ф╨╛╨║╤Г╨╝╨╡╨╜╤В╨а╨░╤Б╤И╨╕╤А╨╡╨╜╨╕╨╡"
      WHERE
        "@╨Ф╨╛╨║╤Г╨╝╨╡╨╜╤В" = d."@╨Ф╨╛╨║╤Г╨╝╨╡╨╜╤В"
    )
  END

рдПрдХ рдкрдЯрдХ рд╣рд╛рдореАрд▓рд╛рдИ рд▓рд┐рдЩреНрдХ рдЧрд░рд┐рдПрдХреЛ рддрд╛рд▓рд┐рдХрд╛рдмрд╛рдЯ рдирддрд┐рдЬрд╛рдХрд╛ рд▓рд╛рдЧрд┐ рдХреБрдиреИ рдкрдирд┐ рдХреНрд╖реЗрддреНрд░ рдЖрд╡рд╢реНрдпрдХ рдкрд░реНрджреИрди, рддреНрдпрд╕рдкрдЫрд┐ рд╣рд╛рдореАрд╕рдБрдЧ рд╕рдмрдХреНрд╡реЗрд░реАрдорд╛ JOIN рд▓рд╛рдИ рд╕рд░реНрддрдорд╛ рдкрд░рд┐рдгрдд рдЧрд░реНрдиреЗ рдЕрд╡рд╕рд░ рдЫред
рдЕрдиреБрдХреНрд░рдордгрд┐рдХрд╛ рдХреНрд╖реЗрддреНрд░рд╣рд░реВ "CASE рдХреЛрд╖реНрдардХ рдмрд╛рд╣рд┐рд░" рдЫреЛрдбреМрдВ, рд░реЗрдХрд░реНрдбрдмрд╛рдЯ WHEN рдмреНрд▓рдХрдорд╛ рд╕рд╛рдзрд╛рд░рдг рд╕рд░реНрддрд╣рд░реВ рдердкреНрдиреБрд╣реЛрд╕реН - рд░ рдЕрдм "рднрд╛рд░реА" рдХреНрд╡реЗрд░реА THEN рдорд╛ рдЬрд╛рдБрджрд╛ рдорд╛рддреНрд░ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдЧрд░рд┐рдиреНрдЫред

рдореЗрд░реЛ рдЕрдиреНрддрд┐рдо рдирд╛рдо "рдХреБрд▓" рд╣реЛ

рд╣рд╛рдореА рдорд╛рдерд┐ рд╡рд░реНрдгрди рдЧрд░рд┐рдПрдХрд╛ рд╕рдмреИ рдореЗрдХрд╛рдирд┐рдХреНрд╕рдХреЛ рд╕рд╛рде рдирддрд┐рдЬрд╛ рдкреНрд░рд╢реНрди рд╕рдЩреНрдХрд▓рди рдЧрд░реНрдЫреМрдВ:

WITH T AS (
  SELECT
    "@╨в╨╕╨┐╨Ф╨╛╨║╤Г╨╝╨╡╨╜╤В╨░"
  FROM
    "╨в╨╕╨┐╨Ф╨╛╨║╤Г╨╝╨╡╨╜╤В╨░"
  WHERE
    "╨в╨╕╨┐╨Ф╨╛╨║╤Г╨╝╨╡╨╜╤В╨░" = '╨Я╨╗╨░╨╜╨а╨░╨▒╨╛╤В'
)
  (
    SELECT
      TRUE
    FROM
      "╨Ф╨╛╨║╤Г╨╝╨╡╨╜╤В" d
    WHERE
      ("╨Ы╨╕╤Ж╨╛3", "╨в╨╕╨┐╨Ф╨╛╨║╤Г╨╝╨╡╨╜╤В╨░") = (19091, (TABLE T)) AND
      CASE
        WHEN "$╨з╨╡╤А╨╜╨╛╨▓╨╕╨║" IS NULL AND "╨г╨┤╨░╨╗╨╡╨╜" IS NOT TRUE THEN (
          SELECT
            "╨б╨╛╤Б╤В╨╛╤П╨╜╨╕╨╡"[1] IS TRUE
          FROM
            "╨Ф╨╛╨║╤Г╨╝╨╡╨╜╤В╨а╨░╤Б╤И╨╕╤А╨╡╨╜╨╕╨╡"
          WHERE
            "@╨Ф╨╛╨║╤Г╨╝╨╡╨╜╤В" = d."@╨Ф╨╛╨║╤Г╨╝╨╡╨╜╤В"
        )
      END
    LIMIT 1
  )
UNION ALL
  (
    SELECT
      TRUE
    FROM
      "╨Ф╨╛╨║╤Г╨╝╨╡╨╜╤В" d
    WHERE
      ("╨в╨╕╨┐╨Ф╨╛╨║╤Г╨╝╨╡╨╜╤В╨░", "╨б╨╛╤В╤А╤Г╨┤╨╜╨╕╨║") = ((TABLE T), 19091) AND
      CASE
        WHEN "$╨з╨╡╤А╨╜╨╛╨▓╨╕╨║" IS NULL AND "╨г╨┤╨░╨╗╨╡╨╜" IS NOT TRUE THEN (
          SELECT
            "╨б╨╛╤Б╤В╨╛╤П╨╜╨╕╨╡"[1] IS TRUE
          FROM
            "╨Ф╨╛╨║╤Г╨╝╨╡╨╜╤В╨а╨░╤Б╤И╨╕╤А╨╡╨╜╨╕╨╡"
          WHERE
            "@╨Ф╨╛╨║╤Г╨╝╨╡╨╜╤В" = d."@╨Ф╨╛╨║╤Г╨╝╨╡╨╜╤В"
        )
      END
    LIMIT 1
  )
LIMIT 1;

рдЕрдиреБрдХреНрд░рдордгрд┐рдХрд╛рд╣рд░реВ рд╕рдорд╛рдпреЛрдЬрди рдЧрд░реНрджреИ

рдПрдХ рдкреНрд░рд╢рд┐рдХреНрд╖рд┐рдд рдЖрдБрдЦрд╛рд▓реЗ рджреЗрдЦреНрдпреЛ рдХрд┐ UNION рд╕рдмрдмреНрд▓рдХрд╣рд░реВрдорд╛ рдЕрдиреБрдХреНрд░рдорд┐рдд рдЕрд╡рд╕реНрдерд╛рд╣рд░реВ рдереЛрд░реИ рдлрд░рдХ рдЫрдиреН - рдпреЛ рдХрд┐рдирднрдиреЗ рд╣рд╛рдореАрд╕рдБрдЧ рддрд╛рд▓рд┐рдХрд╛рдорд╛ рдЙрдкрдпреБрдХреНрдд рдЕрдиреБрдХреНрд░рдордгрд┐рдХрд╛рд╣рд░реВ рдЫрдиреНред рд░ рдпрджрд┐ рддрд┐рдиреАрд╣рд░реВ рдЕрд╡рд╕реНрдерд┐рдд рдЫреИрдирдиреН рднрдиреЗ, рдпреЛ рд╕рд┐рд░реНрдЬрдирд╛ рдЧрд░реНрди рд▓рд╛рдпрдХ рд╣реБрдиреЗрдЫ: рдХрд╛рдЧрдЬрд╛рдд(рд╡реНрдпрдХреНрддрд┐3, рдХрд╛рдЧрдЬрд╛рдд рдкреНрд░рдХрд╛рд░) ╨╕ рдХрд╛рдЧрдЬрд╛рдд (рдХрд╛рдЧрдЬрд╛рдд рдкреНрд░рдХрд╛рд░, рдХрд░реНрдордЪрд╛рд░реА).
ROW рдЕрд╡рд╕реНрдерд╛рд╣рд░реВрдорд╛ рдХреНрд╖реЗрддреНрд░рд╣рд░реВрдХреЛ рдХреНрд░рдордХреЛ рдмрд╛рд░реЗрдорд╛рдпреЛрдЬрдирд╛рдХрд╛рд░рдХреЛ рджреГрд╖реНрдЯрд┐рдХреЛрдгрдмрд╛рдЯ, рдирд┐рд╕реНрд╕рдиреНрджреЗрд╣, рддрдкрд╛рдЗрдБ рд▓реЗрдЦреНрди рд╕рдХреНрдиреБрд╣реБрдиреНрдЫ (A, B) = (constA, constB)рд░ (B, A) = (constB, constA)ред рддрд░ рд░реЗрдХрд░реНрдбрд┐рдЩ рдЧрд░реНрджрд╛ рдЕрдиреБрдХреНрд░рдордгрд┐рдХрд╛рдорд╛ рдХреНрд╖реЗрддреНрд░рд╣рд░реВрдХреЛ рдХреНрд░рдордорд╛, рдпрд╕реНрддреЛ рдЕрдиреБрд░реЛрдз рдкрдЫрд┐ рдбрд┐рдмрдЧ рдЧрд░реНрди рд╕рдЬрд┐рд▓реЛ рдЫред
рдХреЗ рдЫ рдпреЛрдЬрдирд╛рдорд╛ тАЛтАЛ?
PostgreSQL Antipatterns: рд╣рд╛рдирд┐рдХрд╛рд░рдХ JOINs рд░ ORs
[explan.tensor.ru рдорд╛ рд╣реЗрд░реНрдиреБрд╣реЛрд╕реН]

рджреБрд░реНрднрд╛рдЧреНрдпрд╡рд╢, рд╣рд╛рдореА рджреБрд░реНрднрд╛рдЧреНрдпрдкреВрд░реНрдг рдерд┐рдпреМрдВ рд░ рдкрд╣рд┐рд▓реЛ UNION рдмреНрд▓рдХрдорд╛ рдХреЗрд╣рд┐ рдкрдирд┐ рдлреЗрд▓рд╛ рдкрд░реЗрди, рддреНрдпрд╕реИрд▓реЗ рджреЛрд╕реНрд░реЛ рдЕрдЭреИ рдкрдирд┐ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдЧрд░рд┐рдпреЛред рддрд░ рдкрдирд┐ - рдорд╛рддреНрд░ 0.037ms рд░ 11 рдмрдлрд░рд╣рд░реВ!
рд╣рд╛рдореАрд▓реЗ рдЕрдиреБрд░реЛрдзрдХреЛ рдЧрддрд┐ рдмрдврд╛рдПрдХрд╛ рдЫреМрдВ рд░ рдореЗрдореЛрд░реАрдорд╛ рдбреЗрдЯрд╛ рдкрдореНрдкрд┐рдЩ рдХрдо рдЧрд░реЗрдХрд╛ рдЫреМрдВ рдзреЗрд░реИ рд╣рдЬрд╛рд░ рдкрдЯрдХ, рдПрдХрджрдо рд╕рд░рд▓ рдкреНрд░рд╡рд┐рдзрд┐рд╣рд░реВ рдкреНрд░рдпреЛрдЧ рдЧрд░реЗрд░ - рдереЛрд░реИ рдкреНрд░рддрд┐рд▓рд┐рдкрд┐-рдкреЗрд╕реНрдЯрдХреЛ рд╕рд╛рде рд░рд╛рдореНрд░реЛ рдкрд░рд┐рдгрд╛рдоред ЁЯЩВ

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

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