PostgreSQL Antipatterns: рдирд╛рдо рд╕реЗ рдЦреЛрдЬ рдХреЗ рдкреБрдирд░рд╛рд╡реГрддреНрдд рд╢реЛрдзрди рдХреА рдХрд╣рд╛рдиреА, рдпрд╛ "рдЖрдЧреЗ рдФрд░ рдкреАрдЫреЗ рдХрд╛ рдЕрдиреБрдХреВрд▓рди"

рджреЗрд╢ рднрд░ рдХреЗ рдмрд┐рдХреНрд░реА рдХрд╛рд░реНрдпрд╛рд▓рдпреЛрдВ рдХреЗ рд╣рдЬрд╛рд░реЛрдВ рдкреНрд░рдмрдВрдзрдХ рд░рд┐рдХреЙрд░реНрдб рдмрдирд╛рддреЗ рд╣реИрдВ рд╣рдорд╛рд░рд╛ рд╕реАрдЖрд░рдПрдо рд╕рд┐рд╕реНрдЯрдо рдкреНрд░рддрд┐рджрд┐рди рд╣рдЬрд╛рд░реЛрдВ рд╕рдВрдкрд░реНрдХ - рд╕рдВрднрд╛рд╡рд┐рдд рдпрд╛ рдореМрдЬреВрджрд╛ рдЧреНрд░рд╛рд╣рдХреЛрдВ рдХреЗ рд╕рд╛рде рд╕рдВрдЪрд╛рд░ рдХреЗ рддрдереНрдпред рдФрд░ рдЗрд╕рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЛ рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ рдПрдХ рдЧреНрд░рд╛рд╣рдХ рдвреВрдВрдврдирд╛ рд╣реЛрдЧрд╛, рдФрд░ рдЕрдзрд┐рдорд╛рдирддрдГ рдмрд╣реБрдд рдЬрд▓реНрджреАред рдФрд░ рдРрд╕рд╛ рдЕрдХреНрд╕рд░ рдирд╛рдо рд╕реЗ рд╣реЛрддрд╛ рд╣реИ.

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

рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдЖрдЧреЗ рдХреА рдЬрд╛рдВрдЪ рд╕реЗ рдПрдХ рджрд┐рд▓рдЪрд╕реНрдк рдЙрджрд╛рд╣рд░рдг рд╕рд╛рдордиреЗ рдЖрдпрд╛ рдкрд╣рд▓реЗ рдЕрдиреБрдХреВрд▓рди рдФрд░ рдлрд┐рд░ рдкреНрд░рджрд░реНрд╢рди рдореЗрдВ рдЧрд┐рд░рд╛рд╡рдЯ рдХрдИ рдЯреАрдореЛрдВ рджреНрд╡рд╛рд░рд╛ рдЗрд╕рдХреЗ рдХреНрд░рдорд┐рдХ рдкрд░рд┐рд╢реЛрдзрди рдХреЗ рд╕рд╛рде рдЕрдиреБрд░реЛрдз рдХрд┐рдпрд╛ рдЧрдпрд╛, рдЬрд┐рдирдореЗрдВ рд╕реЗ рдкреНрд░рддреНрдпреЗрдХ рдиреЗ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рд╕рд░реНрд╡реЛрддреНрддрдо рдЗрд░рд╛рджреЛрдВ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд┐рдпрд╛ред

0: рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреНрдпрд╛ рдЪрд╛рд╣рддрд╛ рдерд╛?

PostgreSQL Antipatterns: рдирд╛рдо рд╕реЗ рдЦреЛрдЬ рдХреЗ рдкреБрдирд░рд╛рд╡реГрддреНрдд рд╢реЛрдзрди рдХреА рдХрд╣рд╛рдиреА, рдпрд╛ "рдЖрдЧреЗ рдФрд░ рдкреАрдЫреЗ рдХрд╛ рдЕрдиреБрдХреВрд▓рди"[рдХреЗрдбреАрдкреАрд╡реА рдЕрдд:]

рдЬрдм рдХреЛрдИ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдирд╛рдо рд╕реЗ "рддреНрд╡рд░рд┐рдд" рдЦреЛрдЬ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдмрд╛рдд рдХрд░рддрд╛ рд╣реИ рддреЛ рдЙрд╕рдХрд╛ рдЖрдорддреМрд░ рдкрд░ рдХреНрдпрд╛ рдорддрд▓рдм рд╣реЛрддрд╛ рд╣реИ? рдпрд╣ рд▓рдЧрднрдЧ рдХрднреА рднреА рдХрд┐рд╕реА рд╕рдмрд╕реНрдЯреНрд░рд┐рдВрдЧ рдЬреИрд╕реЗ "рдИрдорд╛рдирджрд╛рд░" рдЦреЛрдЬ рдХреЗ рд░реВрдк рдореЗрдВ рд╕рд╛рдордиреЗ рдирд╣реАрдВ рдЖрддрд╛ рд╣реИ ... LIKE '%╤А╨╛╨╖╨░%' - рдХреНрдпреЛрдВрдХрд┐ рддрдм рдкрд░рд┐рдгрд╛рдо рдореЗрдВ рди рдХреЗрд╡рд▓ рд╢рд╛рдорд┐рд▓ рд╣реЛрддрд╛ рд╣реИ '╨а╨╛╨╖╨░╨╗╨╕╤П' ╨╕ '╨Ь╨░╨│╨░╨╖╨╕╨╜ ╨а╨╛╨╖╨░'рд▓реЗрдХрд┐рди '╨У╤А╨╛╨╖╨░' рдФрд░ рдпрд╣рд╛рдВ рддрдХ тАЛтАЛрдХрд┐ '╨Ф╨╛╨╝ ╨Ф╨╡╨┤╨░ ╨Ь╨╛╤А╨╛╨╖╨░'.

рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рд░реЛрдЬрдорд░реНрд░рд╛ рдХреЗ рд╕реНрддрд░ рдкрд░ рдпрд╣ рдорд╛рдирддрд╛ рд╣реИ рдХрд┐ рдЖрдк рдЙрд╕реЗ рдХреНрдпрд╛ рдкреНрд░рджрд╛рди рдХрд░реЗрдВрдЧреЗ рд╢рдмреНрдж рдХреА рд╢реБрд░реБрдЖрдд рд╕реЗ рдЦреЛрдЬреЗрдВ рд╢реАрд░реНрд╖рдХ рдореЗрдВ рдФрд░ рдЗрд╕реЗ рдФрд░ рдЕрдзрд┐рдХ рдкреНрд░рд╛рд╕рдВрдЧрд┐рдХ рдмрдирд╛рдПрдВ рдЗрд╕рдХреЗ рд╕рд╛рде рдЖрд░рдВрдн рд╣реЛрддрд╛ рд╣реИ рдкреНрд░рд╡рд┐рд╖реНрдЯрд┐ рдХреАред рдФрд░ рдЖрдк рдпрд╣ рдХрд░реЗрдВрдЧреЗ рд▓рдЧрднрдЧ рддреБрд░рдиреНрдд - рдЗрдВрдЯрд░рд▓реАрдирд┐рдпрд░ рдЗрдирдкреБрдЯ рдХреЗ рд▓рд┐рдП.

1: рдХрд╛рд░реНрдп рдХреЛ рд╕реАрдорд┐рдд рдХрд░реЗрдВ

рдФрд░ рдЗрд╕рд╕реЗ рднреА рдЕрдзрд┐рдХ, рдХреЛрдИ рд╡реНрдпрдХреНрддрд┐ рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ рдкреНрд░рд╡реЗрд╢ рдирд╣реАрдВ рдХрд░реЗрдЧрд╛ '╤А╨╛╨╖ ╨╝╨░╨│╨░╨╖', рддрд╛рдХрд┐ рдЖрдкрдХреЛ рдкреНрд░рддреНрдпреЗрдХ рд╢рдмреНрдж рдХреЛ рдЙрдкрд╕рд░реНрдЧ рджреНрд╡рд╛рд░рд╛ рдЦреЛрдЬрдирд╛ рдкрдбрд╝реЗред рдирд╣реАрдВ, рдХрд┐рд╕реА рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЗ рд▓рд┐рдП рдЕрдВрддрд┐рдо рд╢рдмреНрдж рдХреЗ рд▓рд┐рдП рддреНрд╡рд░рд┐рдд рд╕рдВрдХреЗрдд рдХрд╛ рдЬрд╡рд╛рдм рджреЗрдирд╛ рдкрд┐рдЫрд▓реЗ рд╡рд╛рд▓реЗ рдХреЛ рдЬрд╛рдирдмреВрдЭрдХрд░ "рдХрдо рдирд┐рд░реНрджрд┐рд╖реНрдЯ" рдХрд░рдиреЗ рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рдмрд╣реБрдд рдЖрд╕рд╛рди рд╣реИ - рджреЗрдЦреЗрдВ рдХрд┐ рдХреЛрдИ рднреА рдЦреЛрдЬ рдЗрдВрдЬрди рдЗрд╕реЗ рдХреИрд╕реЗ рд╕рдВрднрд╛рд▓рддрд╛ рд╣реИред

рдЖрдо рддреМрд░ рдкрд░, рдареАрдХ рдкреНрд░рдХрд╛рд░ рд╕реЗ рд╕рдорд╕реНрдпрд╛ рдХреЗ рд▓рд┐рдП рдЖрд╡рд╢реНрдпрдХрддрд╛рдУрдВ рдХреЛ рддреИрдпрд╛рд░ рдХрд░рдирд╛ рдЖрдзреЗ рд╕реЗ рдЕрдзрд┐рдХ рд╕рдорд╛рдзрд╛рди рд╣реИред рдХрднреА-рдХрднреА рд╕рд╛рд╡рдзрд╛рдиреАрдкреВрд░реНрд╡рдХ рдХреЗрд╕ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВ рдкрд░рд┐рдгрд╛рдо рдХреЛ рдорд╣рддреНрд╡рдкреВрд░реНрдг рд░реВрдк рд╕реЗ рдкреНрд░рднрд╛рд╡рд┐рдд рдХрд░ рд╕рдХрддрд╛ рд╣реИ.

рдПрдХ рдЕрдореВрд░реНрдд рдбреЗрд╡рд▓рдкрд░ рдХреНрдпрд╛ рдХрд░рддрд╛ рд╣реИ?

1.0: рдмрд╛рд╣реНрдп рдЦреЛрдЬ рдЗрдВрдЬрди

рдУрд╣, рдЦреЛрдЬ рдХрдард┐рди рд╣реИ, рдореИрдВ рдХреБрдЫ рднреА рдирд╣реАрдВ рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ - рдЪрд▓реЛ рдЗрд╕реЗ рджреЗрд╡реЛрдкреНрд╕ рдХреЛ рджреЗ рджреЗрдВ! рдЙрдиреНрд╣реЗрдВ рдбреЗрдЯрд╛рдмреЗрд╕ рдХреЗ рдмрд╛рд╣рд░ рдПрдХ рдЦреЛрдЬ рдЗрдВрдЬрди рддреИрдирд╛рдд рдХрд░рдиреЗ рджреЗрдВ: рд╕реНрдлрд┐рдВрдХреНрд╕, рдЗрд▓рд╛рд╕реНрдЯрд┐рдХрд╕рд░реНрдЪ,...

рдПрдХ рдХрд╛рдордХрд╛рдЬреА рд╡рд┐рдХрд▓реНрдк, рдпрджреНрдпрдкрд┐ рд╕рд┐рдВрдХреНрд░рдирд╛рдЗрдЬрд╝реЗрд╢рди рдФрд░ рдкрд░рд┐рд╡рд░реНрддрдиреЛрдВ рдХреА рдЧрддрд┐ рдХреЗ рдорд╛рдорд▓реЗ рдореЗрдВ рд╢реНрд░рдо-рдЧрд╣рдиред рд▓реЗрдХрд┐рди рд╣рдорд╛рд░реЗ рдорд╛рдорд▓реЗ рдореЗрдВ рдирд╣реАрдВ, рдХреНрдпреЛрдВрдХрд┐ рдкреНрд░рддреНрдпреЗрдХ рдЧреНрд░рд╛рд╣рдХ рдХреА рдЦреЛрдЬ рдЙрд╕рдХреЗ рдЦрд╛рддрд╛ рдбреЗрдЯрд╛ рдХреЗ рдврд╛рдВрдЪреЗ рдХреЗ рднреАрддрд░ рд╣реА рдХреА рдЬрд╛рддреА рд╣реИред рдФрд░ рдбреЗрдЯрд╛ рдореЗрдВ рдХрд╛рдлреА рдЙрдЪреНрдЪ рдкрд░рд┐рд╡рд░реНрддрдирд╢реАрд▓рддрд╛ рд╣реИ - рдФрд░ рдпрджрд┐ рдкреНрд░рдмрдВрдзрдХ рдиреЗ рдЕрдм рдХрд╛рд░реНрдб рдореЗрдВ рдкреНрд░рд╡реЗрд╢ рдХрд┐рдпрд╛ рд╣реИ '╨Ь╨░╨│╨░╨╖╨╕╨╜ ╨а╨╛╨╖╨░', рдлрд┐рд░ 5-10 рд╕реЗрдХрдВрдб рдХреЗ рдмрд╛рдж рдЙрд╕реЗ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдпрд╛рдж рдЖ рд╕рдХрддрд╛ рд╣реИ рдХрд┐ рд╡рд╣ рд╡рд╣рд╛рдВ рдЕрдкрдирд╛ рдИрдореЗрд▓ рдЗрдВрдЧрд┐рдд рдХрд░рдирд╛ рднреВрд▓ рдЧрдпрд╛ рд╣реИ рдФрд░ рдЙрд╕реЗ рдвреВрдВрдврдирд╛ рдФрд░ рдЙрд╕реЗ рдареАрдХ рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реИред

рдЗрд╕рд▓рд┐рдП - рдЪрд▓реЛ "рд╕реАрдзреЗ рдбреЗрдЯрд╛рдмреЗрд╕ рдореЗрдВ" рдЦреЛрдЬреЗрдВ. рд╕реМрднрд╛рдЧреНрдп рд╕реЗ, PostgreSQL рд╣рдореЗрдВ рдРрд╕рд╛ рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ, рди рдХрд┐ рдХреЗрд╡рд▓ рдПрдХ рд╡рд┐рдХрд▓реНрдк - рд╣рдо рдЙрди рдкрд░ рдЧреМрд░ рдХрд░реЗрдВрдЧреЗред

1.1: "рдИрдорд╛рдирджрд╛рд░" рд╕рдмрд╕реНрдЯреНрд░рд┐рдВрдЧ

рд╣рдо "рд╕рдмрд╕реНрдЯреНрд░рд┐рдВрдЧ" рд╢рдмреНрдж рд╕реЗ рдЪрд┐рдкрдХреЗ рд╣реБрдП рд╣реИрдВред рд▓реЗрдХрд┐рди рд╕рдмрд╕реНрдЯреНрд░рд┐рдВрдЧ рджреНрд╡рд╛рд░рд╛ рд╕реВрдЪрдХрд╛рдВрдХ рдЦреЛрдЬ рдХреЗ рд▓рд┐рдП (рдФрд░ рдирд┐рдпрдорд┐рдд рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рджреНрд╡рд╛рд░рд╛ рднреА!) рдПрдХ рдЙрддреНрдХреГрд╖реНрдЯ рд╣реИ рдореЙрдбреНрдпреВрд▓ pg_trgm! рддрднреА рд╕рд╣реА рдврдВрдЧ рд╕реЗ рдХреНрд░рдордмрджреНрдз рдХрд░рдирд╛ рдЖрд╡рд╢реНрдпрдХ рд╣реЛрдЧрд╛ред

рдЖрдЗрдП рдореЙрдбрд▓ рдХреЛ рд╕рд░рд▓ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдкреНрд▓реЗрдЯ рд▓реЗрдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░реЗрдВ:

CREATE TABLE firms(
  id
    serial
      PRIMARY KEY
, name
    text
);

рд╣рдо рд╡рд╣рд╛рдВ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рд╕рдВрдЧрдардиреЛрдВ рдХреЗ 7.8 рдорд┐рд▓рд┐рдпрди рд░рд┐рдХреЙрд░реНрдб рдЕрдкрд▓реЛрдб рдХрд░рддреЗ рд╣реИрдВ рдФрд░ рдЙрдиреНрд╣реЗрдВ рдЕрдиреБрдХреНрд░рдорд┐рдд рдХрд░рддреЗ рд╣реИрдВ:

CREATE EXTENSION pg_trgm;
CREATE INDEX ON firms USING gin(lower(name) gin_trgm_ops);

рдЖрдЗрдП рдЗрдВрдЯрд░рд▓реАрдирд┐рдпрд░ рдЦреЛрдЬ рдХреЗ рд▓рд┐рдП рдкрд╣рд▓реЗ 10 рд░рд┐рдХреЙрд░реНрдб рджреЗрдЦреЗрдВ:

SELECT
  *
FROM
  firms
WHERE
  lower(name) ~ ('(^|s)' || '╤А╨╛╨╖╨░')
ORDER BY
  lower(name) ~ ('^' || '╤А╨╛╨╖╨░') DESC -- ╤Б╨╜╨░╤З╨░╨╗╨░ "╨╜╨░╤З╨╕╨╜╨░╤О╤Й╨╕╨╡╤Б╤П ╨╜╨░"
, lower(name) -- ╨╛╤Б╤В╨░╨╗╤М╨╜╨╛╨╡ ╨┐╨╛ ╨░╨╗╤Д╨░╨▓╨╕╤В╤Г
LIMIT 10;

PostgreSQL Antipatterns: рдирд╛рдо рд╕реЗ рдЦреЛрдЬ рдХреЗ рдкреБрдирд░рд╛рд╡реГрддреНрдд рд╢реЛрдзрди рдХреА рдХрд╣рд╛рдиреА, рдпрд╛ "рдЖрдЧреЗ рдФрд░ рдкреАрдЫреЗ рдХрд╛ рдЕрдиреБрдХреВрд▓рди"
[рджреЗрдЦреЗрдВ рд╡реНрдпрд╛рдЦреНрдпрд╛.рдЯреЗрдВрд╕рд░.рдЖрд░рдпреВ]

рдХрд┐... 26 рдПрдордПрд╕, 31 рдПрдордмреА рдбреЗрдЯрд╛ рдкрдврд╝реЗрдВ рдФрд░ 1.7K рд╕реЗ рдЕрдзрд┐рдХ рдлрд╝рд┐рд▓реНрдЯрд░ рдХрд┐рдП рдЧрдП рд░рд┐рдХреЙрд░реНрдб - 10 рдЦреЛрдЬреЗ рдЧрдП рдХреЗ рд▓рд┐рдПред рдУрд╡рд░рд╣реЗрдб рд▓рд╛рдЧрдд рдмрд╣реБрдд рдЕрдзрд┐рдХ рд╣реИ, рдХреНрдпрд╛ рдХреБрдЫ рдЕрдзрд┐рдХ рдХреБрд╢рд▓ рдирд╣реАрдВ рд╣реИ?

1.2: рдкрд╛рда рджреНрд╡рд╛рд░рд╛ рдЦреЛрдЬреЗрдВ? рдпрд╣ рдПрдлрдЯреАрдПрд╕ рд╣реИ!

рджрд░рдЕрд╕рд▓, PostgreSQL рдмрд╣реБрдд рд╢рдХреНрддрд┐рд╢рд╛рд▓реА рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИ рдкреВрд░реНрдг рдкрд╛рда рдЦреЛрдЬ рдЗрдВрдЬрди (рдкреВрд░реНрдг рдкрд╛рда рдЦреЛрдЬ), рдЙрдкрд╕рд░реНрдЧ рдЦреЛрдЬ рдХреА рдХреНрд╖рдорддрд╛ рд╕рд╣рд┐рддред рдПрдХ рдмрдврд╝рд┐рдпрд╛ рд╡рд┐рдХрд▓реНрдк, рдЖрдкрдХреЛ рдПрдХреНрд╕рдЯреЗрдВрд╢рди рдЗрдВрд╕реНрдЯреЙрд▓ рдХрд░рдиреЗ рдХреА рднреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИ! рдЖрдУ рдХреЛрд╢рд┐рд╢ рдХрд░рддреЗ рд╣реИрдВ:

CREATE INDEX ON firms USING gin(to_tsvector('simple'::regconfig, lower(name)));

SELECT
  *
FROM
  firms
WHERE
  to_tsvector('simple'::regconfig, lower(name)) @@ to_tsquery('simple', '╤А╨╛╨╖╨░:*')
ORDER BY
  lower(name) ~ ('^' || '╤А╨╛╨╖╨░') DESC
, lower(name)
LIMIT 10;

PostgreSQL Antipatterns: рдирд╛рдо рд╕реЗ рдЦреЛрдЬ рдХреЗ рдкреБрдирд░рд╛рд╡реГрддреНрдд рд╢реЛрдзрди рдХреА рдХрд╣рд╛рдиреА, рдпрд╛ "рдЖрдЧреЗ рдФрд░ рдкреАрдЫреЗ рдХрд╛ рдЕрдиреБрдХреВрд▓рди"
[рджреЗрдЦреЗрдВ рд╡реНрдпрд╛рдЦреНрдпрд╛.рдЯреЗрдВрд╕рд░.рдЖрд░рдпреВ]

рдпрд╣рд╛рдВ рдХреНрд╡реЗрд░реА рдирд┐рд╖реНрдкрд╛рджрди рдХреЗ рд╕рдорд╛рдирд╛рдВрддрд░реАрдХрд░рдг рд╕реЗ рд╣рдореЗрдВ рдереЛрдбрд╝реА рдорджрдж рдорд┐рд▓реА, рдЬрд┐рд╕рд╕реЗ рд╕рдордп рдЖрдзрд╛ рд╣реЛ рдЧрдпрд╛ 11 рдорд┐.рд╕реЗ. рдФрд░ рд╣рдореЗрдВ рдХреБрд▓ рдорд┐рд▓рд╛рдХрд░ 1.5 рдЧреБрдирд╛ рдХрдо рдкрдврд╝рдирд╛ рдкрдбрд╝рд╛ 20MB. рд▓реЗрдХрд┐рди рдпрд╣рд╛рдВ, рдЬрд┐рддрдирд╛ рдХрдо, рдЙрддрдирд╛ рдмреЗрд╣рддрд░, рдХреНрдпреЛрдВрдХрд┐ рдЬрд┐рддрдиреА рдЕрдзрд┐рдХ рдорд╛рддреНрд░рд╛ рдореЗрдВ рд╣рдо рдкрдврд╝рддреЗ рд╣реИрдВ, рдХреИрд╢ рдорд┐рд╕ рд╣реЛрдиреЗ рдХреА рд╕рдВрднрд╛рд╡рдирд╛ рдЙрддрдиреА рд╣реА рдЕрдзрд┐рдХ рд╣реЛрддреА рд╣реИ, рдФрд░ рдбрд┐рд╕реНрдХ рд╕реЗ рдкрдврд╝рд╛ рдЧрдпрд╛ рдбреЗрдЯрд╛ рдХрд╛ рдкреНрд░рддреНрдпреЗрдХ рдЕрддрд┐рд░рд┐рдХреНрдд рдкреГрд╖реНрда рдЕрдиреБрд░реЛрдз рдХреЗ рд▓рд┐рдП рд╕рдВрднрд╛рд╡рд┐рдд "рдмреНрд░реЗрдХ" рд╣реЛрддрд╛ рд╣реИред

1.3: рдЕрднреА рднреА рдкрд╕рдВрдж рд╣реИ?

рдкрд┐рдЫрд▓рд╛ рдЕрдиреБрд░реЛрдз рд╕рднреА рдХреЗ рд▓рд┐рдП рдЕрдЪреНрдЫрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдпрджрд┐ рдЖрдк рдЗрд╕реЗ рджрд┐рди рдореЗрдВ рдПрдХ рд▓рд╛рдЦ рдмрд╛рд░ рдЦреАрдВрдЪреЗрдВрдЧреЗ рддреЛ рд╣реА рдпрд╣ рдЖрдПрдЧрд╛ 2TB рдбреЗрдЯрд╛ рдкрдврд╝реЗрдВ. рд╕рд░реНрд╡реЛрддреНрддрдо рд╕реНрдерд┐рддрд┐ рдореЗрдВ, рдореЗрдореЛрд░реА рд╕реЗ, рд▓реЗрдХрд┐рди рдпрджрд┐ рдЖрдк рдмрджрдХрд┐рд╕реНрдордд рд╣реИрдВ, рддреЛ рдбрд┐рд╕реНрдХ рд╕реЗред рддреЛ рдЖрдЗрдП рдЗрд╕реЗ рдЫреЛрдЯрд╛ рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░реЗрдВред

рдЖрдЗрдП рдпрд╛рдж рд░рдЦреЗрдВ рдХрд┐ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреНрдпрд╛ рджреЗрдЦрдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реИ рдкрд╣рд▓рд╛ "рдЬрд┐рд╕рд╕реЗ рд╢реБрд░реВ рд╣реЛрддрд╛ рд╣реИ...". рддреЛ рдпрд╣ рдЕрдкрдиреЗ рд╢реБрджреНрдзрддрдо рд░реВрдк рдореЗрдВ рд╣реИ рдЙрдкрд╕рд░реНрдЧ рдЦреЛрдЬ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ text_pattern_ops! рдФрд░ рдХреЗрд╡рд▓ рдпрджрд┐ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ 10 рд░рд┐рдХреЙрд░реНрдб рддрдХ "рдкрд░реНрдпрд╛рдкреНрдд рдирд╣реАрдВ" рд╣реИрдВ рдЬрд┐рдиреНрд╣реЗрдВ рд╣рдо рдвреВрдВрдв рд░рд╣реЗ рд╣реИрдВ, рддреЛ рд╣рдореЗрдВ рдПрдлрдЯреАрдПрд╕ рдЦреЛрдЬ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЙрдиреНрд╣реЗрдВ рдкрдврд╝рдирд╛ рд╕рдорд╛рдкреНрдд рдХрд░рдирд╛ рд╣реЛрдЧрд╛:

CREATE INDEX ON firms(lower(name) text_pattern_ops);

SELECT
  *
FROM
  firms
WHERE
  lower(name) LIKE ('╤А╨╛╨╖╨░' || '%')
LIMIT 10;

PostgreSQL Antipatterns: рдирд╛рдо рд╕реЗ рдЦреЛрдЬ рдХреЗ рдкреБрдирд░рд╛рд╡реГрддреНрдд рд╢реЛрдзрди рдХреА рдХрд╣рд╛рдиреА, рдпрд╛ "рдЖрдЧреЗ рдФрд░ рдкреАрдЫреЗ рдХрд╛ рдЕрдиреБрдХреВрд▓рди"
[рджреЗрдЦреЗрдВ рд╡реНрдпрд╛рдЦреНрдпрд╛.рдЯреЗрдВрд╕рд░.рдЖрд░рдпреВ]

рдЙрддреНрдХреГрд╖реНрдЯ рдкреНрд░рджрд░реНрд╢рди - рдХреБрд▓ 0.05ms рдФрд░ 100KB рд╕реЗ рдереЛрдбрд╝рд╛ рдЕрдзрд┐рдХ рдкрдврд╝рдирд╛! рд╣рдо рд╣реА рднреВрд▓ рдЧрдпреЗ рдирд╛рдо рджреНрд╡рд╛рд░рд╛ рдХреНрд░рдордмрджреНрдз рдХрд░реЗрдВрддрд╛рдХрд┐ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдкрд░рд┐рдгрд╛рдореЛрдВ рдореЗрдВ рдЦреЛ рди рдЬрд╛рдП:

SELECT
  *
FROM
  firms
WHERE
  lower(name) LIKE ('╤А╨╛╨╖╨░' || '%')
ORDER BY
  lower(name)
LIMIT 10;

PostgreSQL Antipatterns: рдирд╛рдо рд╕реЗ рдЦреЛрдЬ рдХреЗ рдкреБрдирд░рд╛рд╡реГрддреНрдд рд╢реЛрдзрди рдХреА рдХрд╣рд╛рдиреА, рдпрд╛ "рдЖрдЧреЗ рдФрд░ рдкреАрдЫреЗ рдХрд╛ рдЕрдиреБрдХреВрд▓рди"
[рджреЗрдЦреЗрдВ рд╡реНрдпрд╛рдЦреНрдпрд╛.рдЯреЗрдВрд╕рд░.рдЖрд░рдпреВ]

рдУрд╣, рдХреБрдЫ рдЕрдм рдЗрддрдирд╛ рд╕реБрдВрджрд░ рдирд╣реАрдВ рд╣реИ - рдРрд╕рд╛ рд▓рдЧрддрд╛ рд╣реИ рдЬреИрд╕реЗ рдХреЛрдИ рд╕реВрдЪрдХрд╛рдВрдХ рд╣реИ, рд▓реЗрдХрд┐рди рдЫрдБрдЯрд╛рдИ рдЙрд╕рд╕реЗ рдЖрдЧреЗ рдирд┐рдХрд▓ рдЬрд╛рддреА рд╣реИ... рдмреЗрд╢рдХ, рдпрд╣ рдкрд┐рдЫрд▓реЗ рд╡рд┐рдХрд▓реНрдк рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдХрдИ рдЧреБрдирд╛ рдЕрдзрд┐рдХ рдкреНрд░рднрд╛рд╡реА рд╣реИ, рд▓реЗрдХрд┐рди...

1.4: "рдлрд╝рд╛рдЗрд▓ рдХреЗ рд╕рд╛рде рд╕рдорд╛рдкреНрдд рдХрд░реЗрдВ"

рд▓реЗрдХрд┐рди рдПрдХ рд╕реВрдЪрдХрд╛рдВрдХ рд╣реИ рдЬреЛ рдЖрдкрдХреЛ рд╢реНрд░реЗрдгреА рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рдЦреЛрдЬ рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ рдФрд░ рдлрд┐рд░ рднреА рд╕рд╛рдорд╛рдиреНрдп рд░реВрдк рд╕реЗ рд╕реЙрд░реНрдЯрд┐рдВрдЧ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИ - рдирд┐рдпрдорд┐рдд btree!

CREATE INDEX ON firms(lower(name));

рдЗрд╕рдХреЗ рд▓рд┐рдП рдХреЗрд╡рд▓ рдЕрдиреБрд░реЛрдз рдХреЛ "рдореИрдиреНрдпреБрдЕрд▓ рд░реВрдк рд╕реЗ рдПрдХрддреНрд░ рдХрд░рдирд╛" рд╣реЛрдЧрд╛:

SELECT
  *
FROM
  firms
WHERE
  lower(name) >= '╤А╨╛╨╖╨░' AND
  lower(name) <= ('╤А╨╛╨╖╨░' || chr(65535)) -- ╨┤╨╗╤П UTF8, ╨┤╨╗╤П ╨╛╨┤╨╜╨╛╨▒╨░╨╣╤В╨╛╨▓╤Л╤Е - chr(255)
ORDER BY
   lower(name)
LIMIT 10;

PostgreSQL Antipatterns: рдирд╛рдо рд╕реЗ рдЦреЛрдЬ рдХреЗ рдкреБрдирд░рд╛рд╡реГрддреНрдд рд╢реЛрдзрди рдХреА рдХрд╣рд╛рдиреА, рдпрд╛ "рдЖрдЧреЗ рдФрд░ рдкреАрдЫреЗ рдХрд╛ рдЕрдиреБрдХреВрд▓рди"
[рджреЗрдЦреЗрдВ рд╡реНрдпрд╛рдЦреНрдпрд╛.рдЯреЗрдВрд╕рд░.рдЖрд░рдпреВ]

рдЙрддреНрдХреГрд╖реНрдЯ - рдЫрдБрдЯрд╛рдИ рдХрд╛рдо рдХрд░рддреА рд╣реИ, рдФрд░ рд╕рдВрд╕рд╛рдзрди рдХреА рдЦрдкрдд "рд╕реВрдХреНрд╖реНрдо" рд░рд╣рддреА рд╣реИ, "рд╢реБрджреНрдз" рдПрдлрдЯреАрдПрд╕ рд╕реЗ рд╣рдЬрд╛рд░реЛрдВ рдЧреБрдирд╛ рдЕрдзрд┐рдХ рдкреНрд░рднрд╛рд╡реА! рдЬреЛ рдХреБрдЫ рдмрдЪрд╛ рд╣реИ рдЙрд╕реЗ рдПрдХ рд╣реА рдЕрдиреБрд░реЛрдз рдореЗрдВ рдПрдХ рд╕рд╛рде рд░рдЦрдирд╛ рд╣реИ:

(
  SELECT
    *
  FROM
    firms
  WHERE
    lower(name) >= '╤А╨╛╨╖╨░' AND
    lower(name) <= ('╤А╨╛╨╖╨░' || chr(65535)) -- ╨┤╨╗╤П UTF8, ╨┤╨╗╤П ╨╛╨┤╨╜╨╛╨▒╨░╨╣╤В╨╛╨▓╤Л╤Е ╨║╨╛╨┤╨╕╤А╨╛╨▓╨╛╨║ - chr(255)
  ORDER BY
     lower(name)
  LIMIT 10
)
UNION ALL
(
  SELECT
    *
  FROM
    firms
  WHERE
    to_tsvector('simple'::regconfig, lower(name)) @@ to_tsquery('simple', '╤А╨╛╨╖╨░:*') AND
    lower(name) NOT LIKE ('╤А╨╛╨╖╨░' || '%') -- "╨╜╨░╤З╨╕╨╜╨░╤О╤Й╨╕╨╡╤Б╤П ╨╜╨░" ╨╝╤Л ╤Г╨╢╨╡ ╨╜╨░╤И╨╗╨╕ ╨▓╤Л╤И╨╡
  ORDER BY
    lower(name) ~ ('^' || '╤А╨╛╨╖╨░') DESC -- ╨╕╤Б╨┐╨╛╨╗╤М╨╖╤Г╨╡╨╝ ╤В╤Г ╨╢╨╡ ╤Б╨╛╤А╤В╨╕╤А╨╛╨▓╨║╤Г, ╤З╤В╨╛╨▒╤Л ╨Э╨Х ╨┐╨╛╨╣╤В╨╕ ╨┐╨╛ btree-╨╕╨╜╨┤╨╡╨║╤Б╤Г
  , lower(name)
  LIMIT 10
)
LIMIT 10;

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

рддреЛ рд╣рд╛рдВ, рдЕрдм рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдЯреЗрдмрд▓ рдкрд░ рдмреАрдЯреНрд░реА рдФрд░ рдЬрд┐рди рджреЛрдиреЛрдВ рд╣реИрдВ, рд▓реЗрдХрд┐рди рд╕рд╛рдВрдЦреНрдпрд┐рдХреАрдп рд░реВрдк рд╕реЗ рдпрд╣ рдкрддрд╛ рдЪрд▓рд╛ рд╣реИ 10% рд╕реЗ рднреА рдХрдо рдЕрдиреБрд░реЛрдз рджреВрд╕рд░реЗ рдмреНрд▓реЙрдХ рдХреЗ рдирд┐рд╖реНрдкрд╛рджрди рддрдХ рдкрд╣реБрдВрдЪрддреЗ рд╣реИрдВ. рдЕрд░реНрдерд╛рддреН, рдХрд╛рд░реНрдп рдХреЗ рд▓рд┐рдП рдкрд╣рд▓реЗ рд╕реЗ рдЬреНрдЮрд╛рдд рдРрд╕реА рд╡рд┐рд╢рд┐рд╖реНрдЯ рд╕реАрдорд╛рдУрдВ рдХреЗ рд╕рд╛рде, рд╣рдо рд╕рд░реНрд╡рд░ рд╕рдВрд╕рд╛рдзрдиреЛрдВ рдХреА рдХреБрд▓ рдЦрдкрдд рдХреЛ рд▓рдЧрднрдЧ рдПрдХ рд╣рдЬрд╛рд░ рдЧреБрдирд╛ рдХрдо рдХрд░рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рдереЗ!

1.5*: рд╣рдо рдлрд╝рд╛рдЗрд▓ рдХреЗ рдмрд┐рдирд╛ рдХрд╛рдо рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ

рдЙрдЪреНрдЪрддрд░ LIKE рд╣рдореЗрдВ рдЧрд╝рд▓рдд рд╕реЙрд░реНрдЯрд┐рдВрдЧ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рд╕реЗ рд░реЛрдХрд╛ рдЧрдпрд╛. рд▓реЗрдХрд┐рди USING рдСрдкрд░реЗрдЯрд░ рдХреЛ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рдХреЗ рдЗрд╕реЗ "рд╕рд╣реА рд░рд╛рд╕реНрддреЗ рдкрд░ рд╕реЗрдЯ" рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ:

рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд░реВрдк рд╕реЗ рдпрд╣ рдорд╛рди рд▓рд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ ASC. рдЗрд╕рдХреЗ рдЕрддрд┐рд░рд┐рдХреНрдд, рдЖрдк рдХрд┐рд╕реА рдХреНрд▓реЙрдЬ рдореЗрдВ рдХрд┐рд╕реА рд╡рд┐рд╢рд┐рд╖реНрдЯ рд╕реЙрд░реНрдЯ рдСрдкрд░реЗрдЯрд░ рдХрд╛ рдирд╛рдо рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ USING. рд╕реЙрд░реНрдЯ рдСрдкрд░реЗрдЯрд░ рдХреЛ рдмреА-рдЯреНрд░реА рдСрдкрд░реЗрдЯрд░реЛрдВ рдХреЗ рдХреБрдЫ рдкрд░рд┐рд╡рд╛рд░ рд╕реЗ рдХрдо рдпрд╛ рдЕрдзрд┐рдХ рдХрд╛ рд╕рджрд╕реНрдп рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред ASC рдЖрдорддреМрд░ рдкрд░ рд╕рдорддреБрд▓реНрдп USING < ╨╕ DESC рдЖрдорддреМрд░ рдкрд░ рд╕рдорддреБрд▓реНрдп USING >.

рд╣рдорд╛рд░реЗ рдорд╛рдорд▓реЗ рдореЗрдВ, "рдХрдо" рд╣реИ ~<~:

SELECT
  *
FROM
  firms
WHERE
  lower(name) LIKE ('╤А╨╛╨╖╨░' || '%')
ORDER BY
  lower(name) USING ~<~
LIMIT 10;

PostgreSQL Antipatterns: рдирд╛рдо рд╕реЗ рдЦреЛрдЬ рдХреЗ рдкреБрдирд░рд╛рд╡реГрддреНрдд рд╢реЛрдзрди рдХреА рдХрд╣рд╛рдиреА, рдпрд╛ "рдЖрдЧреЗ рдФрд░ рдкреАрдЫреЗ рдХрд╛ рдЕрдиреБрдХреВрд▓рди"
[рджреЗрдЦреЗрдВ рд╡реНрдпрд╛рдЦреНрдпрд╛.рдЯреЗрдВрд╕рд░.рдЖрд░рдпреВ]

2: рдЕрдиреБрд░реЛрдз рдХреИрд╕реЗ рдЦрд╝рд░рд╛рдм рд╣реЛ рдЬрд╛рддреЗ рд╣реИрдВ

рдЕрдм рд╣рдо рдЕрдкрдирд╛ рдЕрдиреБрд░реЛрдз рдЫрд╣ рдорд╣реАрдиреЗ рдпрд╛ рдПрдХ рд╕рд╛рд▓ рдХреЗ рд▓рд┐рдП "рдЙрдмрд╛рд▓рдиреЗ" рдХреЗ рд▓рд┐рдП рдЫреЛрдбрд╝ рджреЗрддреЗ рд╣реИрдВ, рдФрд░ рд╣рдо рдореЗрдореЛрд░реА рдХреЗ рдХреБрд▓ рджреИрдирд┐рдХ "рдкрдВрдкрд┐рдВрдЧ" рдХреЗ рд╕рдВрдХреЗрддрдХреЛрдВ рдХреЗ рд╕рд╛рде рдЗрд╕реЗ рдлрд┐рд░ рд╕реЗ "рд╢реАрд░реНрд╖ рдкрд░" рдкрд╛рдХрд░ рдЖрд╢реНрдЪрд░реНрдпрдЪрдХрд┐рдд рд╣реИрдВ (рдмрдлрд╝рд░реНрд╕ рдиреЗ рд╣рд┐рдЯ рд╕рд╛рдЭрд╛ рдХреАрдореЗрдВ) 5.5TB - рдпрд╛рдиреА, рдореВрд▓ рд░реВрдк рд╕реЗ рдЙрд╕рд╕реЗ рднреА рдЕрдзрд┐рдХред

рдирд╣реАрдВ, рдмреЗрд╢рдХ, рд╣рдорд╛рд░рд╛ рд╡реНрдпрд╡рд╕рд╛рдп рдмрдврд╝ рдЧрдпрд╛ рд╣реИ рдФрд░ рд╣рдорд╛рд░рд╛ рдХрд╛рд░реНрдпрднрд╛рд░ рдмрдврд╝ рдЧрдпрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдЙрддрдиреА рдорд╛рддреНрд░рд╛ рдореЗрдВ рдирд╣реАрдВ! рдЗрд╕рдХрд╛ рдорддрд▓рдм рд╣реИ рдХрд┐ рдпрд╣рд╛рдВ рдХреБрдЫ рдЧрдбрд╝рдмрдбрд╝ рд╣реИ - рдЖрдЗрдП рдЗрд╕рдХрд╛ рдкрддрд╛ рд▓рдЧрд╛рдПрдВред

2.1: рдкреЗрдЬрд┐рдВрдЧ рдХрд╛ рдЬрдиреНрдо

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

( ... LIMIT <N> + 10)
UNION ALL
( ... LIMIT <N> + 10)
LIMIT 10 OFFSET <N>;

рдЕрдм рдбреЗрд╡рд▓рдкрд░ рдХреЗ рд▓рд┐рдП рдмрд┐рдирд╛ рдХрд┐рд╕реА рддрдирд╛рд╡ рдХреЗ "рдкреЗрдЬ-рджрд░-рдкреЗрдЬ" рд▓реЛрдбрд┐рдВрдЧ рдХреЗ рд╕рд╛рде рдЦреЛрдЬ рдкрд░рд┐рдгрд╛рдореЛрдВ рдХреА рд░рдЬрд┐рд╕реНрдЯреНрд░реА рджрд┐рдЦрд╛рдирд╛ рд╕рдВрднрд╡ рдерд╛ред

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

2.2: рдореБрдЭреЗ рдХреБрдЫ рд╡рд┐рджреЗрд╢реА рдЪрд╛рд╣рд┐рдП

рдХрд┐рд╕реА рдмрд┐рдВрджреБ рдкрд░ рдбреЗрд╡рд▓рдкрд░ рдЪрд╛рд╣рддрд╛ рдерд╛ рдбреЗрдЯрд╛ рдХреЗ рд╕рд╛рде рдкрд░рд┐рдгрд╛рдореА рдирдореВрдиреЗ рдореЗрдВ рд╡рд┐рд╡рд┐рдзрддрд╛ рд▓рд╛рдПрдВ рдХрд┐рд╕реА рдЕрдиреНрдп рддрд╛рд▓рд┐рдХрд╛ рд╕реЗ, рдЬрд┐рд╕рдХреЗ рд▓рд┐рдП рдкрд┐рдЫрд▓рд╛ рдкреВрд░рд╛ рдЕрдиреБрд░реЛрдз CTE рдХреЛ рднреЗрдЬрд╛ рдЧрдпрд╛ рдерд╛:

WITH q AS (
  ...
  LIMIT <N> + 10
)
SELECT
  *
, (SELECT ...) sub_query -- ╨║╨░╨║╨╛╨╣-╤В╨╛ ╨╖╨░╨┐╤А╨╛╤Б ╨║ ╤Б╨▓╤П╨╖╨░╨╜╨╜╨╛╨╣ ╤В╨░╨▒╨╗╨╕╤Ж╨╡
FROM
  q
LIMIT 10 OFFSET <N>;

рдФрд░ рдлрд┐рд░ рднреА, рдпрд╣ рдмреБрд░рд╛ рдирд╣реАрдВ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рд╕рдмрдХреНрд╡реЗрд░реА рдХрд╛ рдореВрд▓реНрдпрд╛рдВрдХрди рдХреЗрд╡рд▓ 10 рд▓реМрдЯрд╛рдП рдЧрдП рд░рд┐рдХреЙрд░реНрдб рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдпрджрд┐ рдирд╣реАрдВ ...

2.3: DISTINCT рд╕рдВрд╡реЗрджрдирд╣реАрди рдФрд░ рдирд┐рд░реНрджрдпреА рд╣реИ

рджреВрд╕рд░реА рд╕рдмрдХреНрд╡реЗрд░реА рд╕реЗ рдРрд╕реЗ рд╡рд┐рдХрд╛рд╕ рдХреА рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдореЗрдВ рдХрд╣реАрдВ рдЦреЛ рдЧрдпрд╛ NOT LIKE рд╢рд░реНрдд. рд╕рд╛рдл рд╣реИ рдХрд┐ рдЗрд╕рдХреЗ рдмрд╛рдж UNION ALL рд▓реМрдЯрдиреЗ рд▓рдЧрд╛ рдХреБрдЫ рдкреНрд░рд╡рд┐рд╖реНрдЯрд┐рдпрд╛рдБ рджреЛ рдмрд╛рд░ - рдкрд╣рд▓реЗ рдкрдВрдХреНрддрд┐ рдХреА рд╢реБрд░реБрдЖрдд рдореЗрдВ рдкрд╛рдпрд╛ рдЧрдпрд╛, рдФрд░ рдлрд┐рд░ рджреЛрдмрд╛рд░рд╛ - рдЗрд╕ рдкрдВрдХреНрддрд┐ рдХреЗ рдкрд╣рд▓реЗ рд╢рдмреНрдж рдХреА рд╢реБрд░реБрдЖрдд рдореЗрдВред рд╕реАрдорд╛ рдореЗрдВ, рджреВрд╕рд░реА рд╕рдмрдХреНрд╡реЗрд░реА рдХреЗ рд╕рднреА рд░рд┐рдХреЙрд░реНрдб рдкрд╣рд▓реЗ рдХреЗ рд░рд┐рдХреЙрд░реНрдб рд╕реЗ рдореЗрд▓ рдЦрд╛ рд╕рдХрддреЗ рд╣реИрдВред

рдХреЛрдИ рдбреЗрд╡рд▓рдкрд░ рдХрд╛рд░рдг рдвреВрдВрдврдиреЗ рдХреЗ рдмрдЬрд╛рдп рдХреНрдпрд╛ рдХрд░рддрд╛ рд╣реИ?.. рдХреЛрдИ рдкреНрд░рд╢реНрди рдирд╣реАрдВ!

  • рдЖрдХрд╛рд░ рджреЛрдЧреБрдирд╛ рдХрд░реЗрдВ рдореВрд▓ рдирдореВрдиреЗ
  • DISTINCT рд▓рд╛рдЧреВ рдХрд░реЗрдВрдкреНрд░рддреНрдпреЗрдХ рдкрдВрдХреНрддрд┐ рдХреЗ рдХреЗрд╡рд▓ рдПрдХрд▓ рдЙрджрд╛рд╣рд░рдг рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП

WITH q AS (
  ( ... LIMIT <2 * N> + 10)
  UNION ALL
  ( ... LIMIT <2 * N> + 10)
  LIMIT <2 * N> + 10
)
SELECT DISTINCT
  *
, (SELECT ...) sub_query
FROM
  q
LIMIT 10 OFFSET <N>;

рдпрд╛рдиреА, рдпрд╣ рд╕реНрдкрд╖реНрдЯ рд╣реИ рдХрд┐ рдкрд░рд┐рдгрд╛рдо, рдЕрдВрдд рдореЗрдВ, рдмрд┐рд▓реНрдХреБрд▓ рд╡реИрд╕рд╛ рд╣реА рд╣реИ, рд▓реЗрдХрд┐рди рджреВрд╕рд░реА рд╕реАрдЯреАрдИ рд╕рдмрдХреНрд╡реЗрд░реА рдореЗрдВ "рдЙрдбрд╝рд╛рди" рдХреА рд╕рдВрднрд╛рд╡рдирд╛ рдмрд╣реБрдд рдЕрдзрд┐рдХ рд╣реЛ рдЧрдИ рд╣реИ, рдФрд░ рдЗрд╕рдХреЗ рдмрд┐рдирд╛ рднреА, рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рдЕрдзрд┐рдХ рдкрдардиреАрдп.

рд▓реЗрдХрд┐рди рдпреЗ рд╕рдмрд╕реЗ рджреБрдЦрдж рдмрд╛рдд рдирд╣реАрдВ рд╣реИ. рдЪреВрдБрдХрд┐ рдбреЗрд╡рд▓рдкрд░ рдиреЗ рдЪрдпрди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд╣рд╛ рдерд╛ DISTINCT рд╡рд┐рд╢рд┐рд╖реНрдЯ рдХреНрд╖реЗрддреНрд░реЛрдВ рдХреЗ рд▓рд┐рдП рдирд╣реАрдВ, рдмрд▓реНрдХрд┐ рдПрдХ рд╣реА рдмрд╛рд░ рдореЗрдВ рд╕рднреА рдХреНрд╖реЗрддреНрд░реЛрдВ рдХреЗ рд▓рд┐рдП рд░рд┐рдХреЙрд░реНрдбреНрд╕, рдлрд┐рд░ рд╕рдм_рдХреНрд╡реЗрд░реА рдлрд╝реАрд▓реНрдб - рд╕рдмрдХреНрд╡реЗрд░реА рдХрд╛ рдкрд░рд┐рдгрд╛рдо - рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рд░реВрдк рд╕реЗ рд╡рд╣рд╛рдВ рд╢рд╛рдорд┐рд▓ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ред рдЕрдм, рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП DISTINCT, рдбреЗрдЯрд╛рдмреЗрд╕ рдХреЛ рдкрд╣рд▓реЗ рд╣реА рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░рдирд╛ рдерд╛ 10 рдЙрдкрд╢реНрд░реЗрдгрд┐рдпрд╛рдБ рдирд╣реАрдВ, рдмрд▓реНрдХрд┐ рд╕рднреА <2 * рдПрди> + 10!

2.4: рд╕рд╣рдпреЛрдЧ рд╕рд░реНрд╡реЛрдкрд░рд┐!

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

рдЬрдм рддрдХ рджреВрд╕рд░реЗ рд╡рд┐рднрд╛рдЧ рдХреЗ рдбреЗрд╡рд▓рдкрд░реНрд╕ рдЙрдирдХреЗ рдкрд╛рд╕ рдирд╣реАрдВ рдЖрдП рдФрд░ рдРрд╕реА рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рд╡рд┐рдзрд┐ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рдереЗ рдкреБрдирд░рд╛рд╡реГрддреНрддреАрдп рдЦреЛрдЬ рдХреЗ рд▓рд┐рдП - рдпрд╛рдиреА, рд╣рдо рдХреБрдЫ рдирдореВрдиреЗ рд╕реЗ рдПрдХ рдЯреБрдХрдбрд╝рд╛ рд▓реЗрддреЗ рд╣реИрдВ, рдЗрд╕реЗ рдЕрддрд┐рд░рд┐рдХреНрдд рд╢рд░реНрддреЛрдВ рдХреЗ рдЕрдиреБрд╕рд╛рд░ рдлрд╝рд┐рд▓реНрдЯрд░ рдХрд░рддреЗ рд╣реИрдВ, рдкрд░рд┐рдгрд╛рдо рдирд┐рдХрд╛рд▓рддреЗ рд╣реИрдВ, рдлрд┐рд░ рдЕрдЧрд▓рд╛ рдЯреБрдХрдбрд╝рд╛ (рдЬреЛ рд╣рдорд╛рд░реЗ рдорд╛рдорд▓реЗ рдореЗрдВ рдПрди рдмрдврд╝рд╛рдХрд░ рд╣рд╛рд╕рд┐рд▓ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ), рдФрд░ рдЗрд╕реА рддрд░рд╣ рдЬрдм рддрдХ рд╣рдо рд╕реНрдХреНрд░реАрди рдирд╣реАрдВ рднрд░ рджреЗрддреЗред

рд╕рд╛рдорд╛рдиреНрдп рддреМрд░ рдкрд░, рдкрдХрдбрд╝реЗ рдЧрдП рдирдореВрдиреЗ рдореЗрдВ N рд▓рдЧрднрдЧ 17K рдХреЗ рдорд╛рди рддрдХ рдкрд╣реБрдВрдЪ рдЧрдпрд╛, рдФрд░ рдХреЗрд╡рд▓ рдПрдХ рджрд┐рди рдореЗрдВ рдХрдо рд╕реЗ рдХрдо 4K рдРрд╕реЗ рдЕрдиреБрд░реЛрдзреЛрдВ рдХреЛ "рд╢реНрд░реГрдВрдЦрд▓рд╛ рдХреЗ рд╕рд╛рде" рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ред рдЙрдирдореЗрдВ рд╕реЗ рдЕрдВрддрд┐рдо рдХреЛ рд╕рд╛рд╣рд╕рдкреВрд░реНрд╡рдХ рд╕реНрдХреИрди рдХрд┐рдпрд╛ рдЧрдпрд╛ рдкреНрд░рддрд┐ рдкреБрдирд░рд╛рд╡реГрддреНрддрд┐ 1GB рдореЗрдореЛрд░реА...

рдХреБрд▓ рдорд┐рд▓рд╛рдХрд░

PostgreSQL Antipatterns: рдирд╛рдо рд╕реЗ рдЦреЛрдЬ рдХреЗ рдкреБрдирд░рд╛рд╡реГрддреНрдд рд╢реЛрдзрди рдХреА рдХрд╣рд╛рдиреА, рдпрд╛ "рдЖрдЧреЗ рдФрд░ рдкреАрдЫреЗ рдХрд╛ рдЕрдиреБрдХреВрд▓рди"

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

рдПрдХ рдЯрд┐рдкреНрдкрдгреА рдЬреЛрдбрд╝реЗрдВ