PostgreSQL Antipatterns: рд▓реЛрдб рдХреЗ рддрд╣рдд рдПрдХ рдмрдбрд╝реА рддрд╛рд▓рд┐рдХрд╛ рдХреЛ рдЕрдкрдбреЗрдЯ рдХрд░рдирд╛

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



рдкрд░реАрдХреНрд╖рдг рдбреЗрдЯрд╛ рддреИрдпрд╛рд░ рдХрд░реЗрдВ:

CREATE TABLE tbl(k text, v integer); INSERT INTO tbl SELECT chr(ascii('a'::text) + (random() * 26)::integer) k , (random() * 100)::integer v FROM generate_series(1, 1000000) i; --  ,   ! CREATE INDEX ON tbl(k, v); 

рдорд╛рди рд▓реАрдЬрд┐рдП рдХрд┐ рд╣рдо рд╕рд┐рд░реНрдл just q тАЩ..тАЩ z тАЩрд╢реНрд░реЗрдгреА рдореЗрдВ k рдХреЗ рд╕рд╛рде рд╕рднреА рд░рд┐рдХреЙрд░реНрдб рдХреЗ рд▓рд┐рдП v рдХреЗ рдорд╛рди рдХреЛ 1 рд╕реЗ рдмрдврд╝рд╛рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВред

рд▓реЗрдХрд┐рди, рдкреНрд░рдпреЛрдЧреЛрдВ рдХреЛ рд╢реБрд░реВ рдХрд░рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ, рд╣рдо рд╣рд░ рдмрд╛рд░ "рд╕рд╛рдл" рдкрд░рд┐рдгрд╛рдо рджреЗрдиреЗ рдХреЗ рд▓рд┐рдП рдореВрд▓ рдбреЗрдЯрд╛рд╕реЗрдЯ рдХреЛ рд╕рд╣реЗрдЬреЗрдВрдЧреЗ:

 CREATE TABLE _tbl AS TABLE tbl; 

рдЕрджреНрдпрддрди: рд╕рднреА рдХреЗ рд▓рд┐рдП рдПрдХ, рдФрд░ рд╕рднреА рдПрдХ рдХреЗ рд▓рд┐рдП


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

 UPDATE tbl SET v = v + 1 WHERE k BETWEEN 'q' AND 'z'; 


[рд╕реНрдкрд╖реНрдЯреАрдХрд░рдг рдкрд░ рджреЗрдЦреЗрдВ редensor.ru]

рдмрд▓реНрдХрд┐ рд╕рд░рд▓, рдпрд╣ рдкреНрд░рддреАрдд рд╣реЛрддрд╛ рд╣реИ, рдкреВрд░реА рддрд░рд╣ рд╕реЗ "рдЫреЛрдЯреА" рд▓рд╛рдЗрдиреЛрдВ рдкрд░ рдСрдкрд░реЗрд╢рди 2.5 рд╕реЗрдХрдВрдб рд╕реЗ рдЕрдзрд┐рдХ рд╕рдордп рд▓рдЧрд╛ред рдФрд░ рдпрджрд┐ рдЖрдкрдХреА рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рдЕрдзрд┐рдХ рдЬрдЯрд┐рд▓ рд╣реИ, рддреЛ рд░реЗрдЦрд╛ рдЕрдзрд┐рдХ рдкреНрд░рд╛рдорд╛рдгрд┐рдХ рд╣реИ, рдЕрдзрд┐рдХ рд░рд┐рдХреЙрд░реНрдб рд╣реИрдВ, рдФрд░ рдпрд╣рд╛рдВ рддрдХ тАЛтАЛрдХрд┐ рдХреБрдЫ рдЯреНрд░рд┐рдЧрд░ рднреА рд╣рд╕реНрддрдХреНрд╖реЗрдк рдХрд░рддреЗ рд╣реИрдВ - рд╕рдордп рдорд┐рдирдЯреЛрдВ рддрдХ рдирд╣реАрдВ, рдмрд▓реНрдХрд┐ рдШрдВрдЯреЛрдВ рддрдХ рднреА рдмрдврд╝ рд╕рдХрддрд╛ рд╣реИред рдорд╛рди рд▓реАрдЬрд┐рдП рдХрд┐ рдЖрдк рдкреНрд░рддреАрдХреНрд╖рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рддреИрдпрд╛рд░ рд╣реИрдВ, рдФрд░ рдЖрдкрдХрд╛ рд╢реЗрд╖ рд╕рд┐рд╕реНрдЯрдо, рдЗрд╕ рдЖрдзрд╛рд░ рд╕реЗ рдмрдВрдзрд╛ рд╣реБрдЖ рд╣реИ, рдЕрдЧрд░ рдЗрд╕рдореЗрдВ рд╕рдХреНрд░рд┐рдп рдУрдПрд▓рдЯреАрдкреА рд▓реЛрдб рд╣реИ?

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


┬й wumo.com/wumo

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

рд╡рд┐рднрд╛рдЬрди рд▓реЗрдирджреЗрди


рд╕рд╛рдорд╛рдиреНрдп рддреМрд░ рдкрд░, рд╕рдм рдХреБрдЫ рдмрд╣реБрдд рдЕрдЪреНрдЫрд╛ рдирд╣реАрдВ рд╣реИ рдЕрдЧрд░ рд╕рдм рдХреБрдЫ рдПрдХ рдЕрдиреБрд░реЛрдз рдореЗрдВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рд╣рд╛рдВ, рдФрд░ рднрд▓реЗ рд╣реА рд╣рдо рдПрдХ рдмрдбрд╝реЗ UPDATE рдХреЛ рдХрдИ рдЫреЛрдЯреЗ-рдЫреЛрдЯреЗ рд╣рд┐рд╕реНрд╕реЛрдВ рдореЗрдВ рдмрд╛рдВрдЯ рджреЗрдВ, рд▓реЗрдХрд┐рди рдпрд╣ рд╕рдм рдПрдХ рд▓реЗрди-рджреЗрди рдореЗрдВ рдХрд╛рдо рдХрд░рдирд╛ рдЫреЛрдбрд╝ рджреЗрдВ, рд▓реЙрдХрд┐рдВрдЧ рдХреА рд╕рдорд╕реНрдпрд╛ рд╕рдорд╛рди рд░рд╣реЗрдЧреА, рдХреНрдпреЛрдВрдХрд┐ рдкреВрд░реЗ рд▓реЗрдирджреЗрди рдХреЗ рдЕрдВрдд рддрдХ рдкрд░рд╕реНрдкрд░ рд░рд┐рдХреЙрд░реНрдб рд▓реЙрдХ рд╣реЛрддреЗ рд╣реИрдВред

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

рдХреЙрд▓ рдФрд░ рд▓реЗрдирджреЗрди рдкреНрд░рдмрдВрдзрди


PostgreSQL 11 рд╕реЗ рд╢реБрд░реВ рд╣реЛрдХрд░, рдкреНрд░рдХреНрд░рд┐рдпрд╛рддреНрдордХ рдХреЛрдб рдХреЗ рдЕрдВрджрд░ рд▓реЗрдирджреЗрди рдХрд╛ рдкреНрд░рдмрдВрдзрди рдХрд░рдирд╛ рд╕рдВрднрд╡ рд╣реИ :
рдХреЙрд▓ рдХрдорд╛рдВрдб рджреНрд╡рд╛рд░рд╛, рд╕рд╛рде рд╣реА рд╕рд╛рде рдХреЛрдб рдХреЗ рдЕрдирд╛рдо рдмреНрд▓реЙрдХреЛрдВ рдореЗрдВ (рдбреАрдУ рдХрдорд╛рдВрдб рдореЗрдВ) рдкреНрд░рдХреНрд░рд┐рдпрд╛рдУрдВ рдореЗрдВ, рдЖрдк COMMIT рдФрд░ ROLLBACK рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░рдХреЗ рд▓реЗрдирджреЗрди рдкреВрд░рд╛ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдЗрди рдЖрджреЗрд╢реЛрдВ рдХреЗ рджреНрд╡рд╛рд░рд╛ рд▓реЗрди-рджреЗрди рдкреВрд░рд╛ рд╣реЛрдиреЗ рдХреЗ рдмрд╛рдж, рдПрдХ рдирдпрд╛ рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рд░реВрдк рд╕реЗ рд╢реБрд░реВ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред
рд▓реЗрдХрд┐рди рдпрд╣ рд╕рдВрд╕реНрдХрд░рдг рд╕рднреА рд╕реЗ рджреВрд░ рд╣реИ, рдФрд░ CALL рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреА рдЕрдкрдиреА рд╕реАрдорд╛рдПрдБ рд╣реИрдВред рдЗрд╕рд▓рд┐рдП, рд╣рдо рдмрд╛рд╣рд░реА рд╕рд╛рдзрдиреЛрдВ рдХреЗ рдмрд┐рдирд╛ рдЕрдкрдиреА рд╕рдорд╕реНрдпрд╛ рдХреЛ рд╣рд▓ рдХрд░рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░реЗрдВрдЧреЗ, рдФрд░ рддрд╛рдХрд┐ рдпрд╣ рд╕рднреА рдореМрдЬреВрджрд╛ рд╕рдВрд╕реНрдХрд░рдгреЛрдВ рдкрд░ рдХрд╛рдо рдХрд░реЗ, рдФрд░ рдпрд╣рд╛рдВ рддрдХ тАЛтАЛрдХрд┐ рд╕рд░реНрд╡рд░ рдкрд░ рдХрдо рд╕реЗ рдХрдо рдмрджрд▓рд╛рд╡ рдХреЗ рд╕рд╛рде - рддрд╛рдХрд┐ рдХреБрдЫ рднреА рд╕рдВрдХрд▓рди рдФрд░ рдкреБрдирд░рд╛рд░рдВрдн рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЖрд╡рд╢реНрдпрдХ рди рд╣реЛред

рдЙрд╕реА рдХрд╛рд░рдг рд╕реЗ, рд╣рдо pg_background рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рд╕реНрд╡рд╛рдпрддреНрдд рд▓реЗрдирджреЗрди рдХреЗ рдЖрдпреЛрдЬрди рдХреЗ рд╡рд┐рдХрд▓реНрдк рдкрд░ рд╡рд┐рдЪрд╛рд░ рдирд╣реАрдВ рдХрд░реЗрдВрдЧреЗред

рдЖрдзрд╛рд░ "рдЕрдВрджрд░" рдХрдиреЗрдХреНрд╢рди рдХрд╛ рдкреНрд░рдмрдВрдзрди


PostgreSQL рдиреЗ рдРрддрд┐рд╣рд╛рд╕рд┐рдХ рд░реВрдк рд╕реЗ рд╕реНрд╡рд╛рдпрддреНрдд рд▓реЗрдирджреЗрди рдХрд╛ рдЕрдиреБрдХрд░рдг рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЕрд▓рдЧ-рдЕрд▓рдЧ рддрд░реАрдХреЛрдВ рдХрд╛ рдЗрд╕реНрддреЗрдорд╛рд▓ рдХрд┐рдпрд╛ рд╣реИ, рдЕрд▓рдЧ-рдЕрд▓рдЧ рдЕрддрд┐рд░рд┐рдХреНрдд рдХрдиреЗрдХреНрд╢рди рдкреИрджрд╛ рдХрд░рддрд╛ рд╣реИ - рдЕрддрд┐рд░рд┐рдХреНрдд рдкреНрд░рдХреНрд░рд┐рдпрд╛рддреНрдордХ рднрд╛рд╖рд╛рдУрдВ рдпрд╛ рдорд╛рдирдХ dblink рдореЙрдбреНрдпреВрд▓ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ ред рдЙрддреНрддрд░рд╛рд░реНрджреНрдз рдХрд╛ рд▓рд╛рдн рдпрд╣ рд╣реИ рдХрд┐ рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд░реВрдк рд╕реЗ рдЗрд╕реЗ рдЕрдзрд┐рдХрд╛рдВрд╢ рд╡рд┐рддрд░рдгреЛрдВ рдореЗрдВ рд╢рд╛рдорд┐рд▓ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдФрд░ рдбреЗрдЯрд╛рдмреЗрд╕ рдореЗрдВ рдЗрд╕реЗ рд╕рдХреНрд░рд┐рдп рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХреЗрд╡рд▓ рдПрдХ рдХрдорд╛рдВрдб рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ:

 CREATE EXTENSION dblink; 

"... рдФрд░ рдХрдИ, рдХрдИ рдкреА рдШреГрдгрд┐рдд рдмрдЪреНрдЪреЛрдВ рдХреЛ рд▓рд╛рдпрд╛"


рд▓реЗрдХрд┐рди рдбрдмреНрд▓рд┐рдВрдХ рдмрд╛рдЗрдВрдбрд┐рдВрдЧ рдмрдирд╛рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ, рдЖрдЗрдП рдкрд╣рд▓реЗ рдкрддрд╛ рдХрд░реЗрдВ рдХрд┐ рдПрдХ "рдирд┐рдпрдорд┐рдд рдбреЗрд╡рд▓рдкрд░" рдПрдХ рдмрдбрд╝реЗ рдбреЗрдЯрд╛рд╕реЗрдЯ рдХреЛ рдХреИрд╕реЗ рддреЛрдбрд╝рддрд╛ рд╣реИ, рдЬрд┐рд╕реЗ рдЙрд╕реЗ рдЫреЛрдЯреЗ рд▓реЛрдЧреЛрдВ рдореЗрдВ рдЕрдкрдбреЗрдЯ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИред

Naive LIMIT ... OFFSET


рдкрд╣рд▓рд╛ рд╡рд┐рдЪрд╛рд░ рдПрдХ "рдкреЗрдЬрд┐рдиреЗрд╢рди" рдЦреЛрдЬ рдХрд░рдиреЗ рдХрд╛ рд╣реИ: рдкреНрд░рддреНрдпреЗрдХ рдирдП рдЕрдиреБрд░реЛрдз рдореЗрдВ OFFSET рдХреЛ рдмрдврд╝рд╛рдХрд░ "рдкреНрд░рддреНрдпреЗрдХ рдмрд╛рд░ рдЕрдЧрд▓реЗ рд╣рдЬрд╛рд░ рд░рд┐рдХреЙрд░реНрдб рдХрд╛ рдЪрдпрди рдХрд░реЗрдВ" :

 UPDATE tbl T SET v = Tv + 1 FROM ( SELECT k , v FROM tbl WHERE k BETWEEN 'q' AND 'z' ORDER BY --       k, v --     ! LIMIT $1 OFFSET $2 * $1 ) S WHERE (Tk, Tv) = (Sk, Sv); 

рдЗрд╕ рд╕рдорд╛рдзрд╛рди рдХреЗ рдкреНрд░рджрд░реНрд╢рди рдХрд╛ рдкрд░реАрдХреНрд╖рдг рдХрд░рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ, рд╣рдо рдбреЗрдЯрд╛рд╕реЗрдЯ рдХреЛ рдкреБрдирд░реНрд╕реНрдерд╛рдкрд┐рдд рдХрд░реЗрдВрдЧреЗ:

 TRUNCATE TABLE tbl; INSERT INTO tbl TABLE _tbl; 

рдЬреИрд╕рд╛ рдХрд┐ рд╣рдордиреЗ рдКрдкрд░ рдХреА рдпреЛрдЬрдирд╛ рдореЗрдВ рджреЗрдЦрд╛ рдерд╛, рд╣рдореЗрдВ рд▓рдЧрднрдЧ 384K рд░рд┐рдХреЙрд░реНрдб рдЕрдкрдбреЗрдЯ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрдЧреАред рдЗрд╕рд▓рд┐рдП, рдЖрдЗрдП рддреБрд░рдВрдд рджреЗрдЦреЗрдВ рдХрд┐ рдЕрдкрдбреЗрдЯ рдХреЛ рдЕрдВрдд рдХреЗ рдХрд░реАрдм рдХреИрд╕реЗ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ - 1000 рдкреНрд░рд╡рд┐рд╖реНрдЯрд┐рдпреЛрдВ рдХреЗ 300 рд╡реЗрдВ рдкреБрдирд░рд╛рд╡реГрддреНрддрд┐ рдХреЗ рдХреНрд╖реЗрддреНрд░ рдореЗрдВ :


[рд╕реНрдкрд╖реНрдЯреАрдХрд░рдг рдкрд░ рджреЗрдЦреЗрдВ редensor.ru]

рдУрд╣ ... рдкреВрд░реЗ 1K рд░рд┐рдХреЙрд░реНрдб рдХреЗ рдЕрдВрдд рдореЗрдВ рд╕реИрдВрдкрд▓ рдХреЛ рдЕрдкрдбреЗрдЯ рдХрд░рдирд╛ рд╣рдореЗрдВ рд▓рдЧрднрдЧ рдкреВрд░реЗ рдореВрд▓ рд╕рдВрд╕реНрдХрд░рдг рдЬрд┐рддрдирд╛ рд╣реА рд╕рдордп рд▓рдЧреЗрдЧрд╛!

рдпрд╣ рд╣рдорд╛рд░реА рдкрд╕рдВрдж рдирд╣реАрдВ рд╣реИред рдпрджрд┐ рдЖрдк рдХреБрдЫ рдкреБрдирд░рд╛рд╡реГрддреНрддрд┐рдпреЛрдВ рдФрд░ рдЫреЛрдЯреЗ OFFSET рдорд╛рди рдкреНрд░рд╛рдкреНрдд рдХрд░рддреЗ рд╣реИрдВ рддреЛ рднреА рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рд╕реА рднреА рддрд░рд╣ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рдХреНрдпреЛрдВрдХрд┐ рдбреЗрдЯрд╛рдмреЗрд╕ рдХреЗ рд▓рд┐рдП LIMIT X OFFSET Y " X + Y рд░рд┐рдХреЙрд░реНрдбреНрд╕ рдХреЛ рдШрдЯрд╛рдиреЗ / рдЪреБрдирдиреЗ / рдлреЙрд░реНрдо рдХрд░рдиреЗ рдХреЗ рдмрд░рд╛рдмрд░ рд╣реИ , рдФрд░ рдлрд┐рд░ рдкрд╣рд▓реЗ Y рдХреЛ рдХреВрдбрд╝реЗрджрд╛рди рдореЗрдВ рдлреЗрдВрдХ рджреЗрддрд╛ рд╣реИ ", рдЬреЛ Y рдХреЗ рдмрдбрд╝реЗ рдореВрд▓реНрдпреЛрдВ рдХреЗ рд▓рд┐рдП рджреБрдЦрдж рд▓рдЧрддрд╛ рд╣реИред

рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ, рдЗрд╕ рд╡рд┐рдзрд┐ рдХреЛ рд▓рд╛рдЧреВ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ ! рди рдХреЗрд╡рд▓ рд╣рдо рдЪрдпрди рдХреЗ рд▓рд┐рдП рдЕрджреНрдпрддрди рдореВрд▓реНрдпреЛрдВ рдкрд░ рднрд░реЛрд╕рд╛ рдХрд░рддреЗ рд╣реИрдВ, рд╣рдо рд░рд┐рдХреЙрд░реНрдб рдХреЗ рднрд╛рдЧ рдХреЛ рдЫреЛрдбрд╝ рджреЗрдиреЗ рдХрд╛ рднреА рдЬреЛрдЦрд┐рдо рд░рдЦрддреЗ рд╣реИрдВ, рдФрд░ рдпрджрд┐ рд╕рдорд╛рди рдХреБрдВрдЬрд┐рдпреЛрдВ рд╡рд╛рд▓реЗ рдмреНрд▓реЙрдХ рдкреГрд╖реНрда рд╕реАрдорд╛ рдкрд░ рдЖрддреЗ рд╣реИрдВ рддреЛ рджреВрд╕рд░реЗ рднрд╛рдЧ рдХреЛ рджреЛ рдмрд╛рд░ рдЕрдкрдбреЗрдЯ рдХрд░рддреЗ рд╣реИрдВ:


рдЗрд╕ рдЙрджрд╛рд╣рд░рдг рдореЗрдВ, рд╣рдордиреЗ рджреЛ рдмрд╛рд░ рд╣рд░рд╛ рд░рд┐рдХреЙрд░реНрдб рдЕрдкрдбреЗрдЯ рдХрд┐рдпрд╛, рдФрд░ рд▓рд╛рд▓ рд░рд┐рдХреЙрд░реНрдб рдХрднреА рдирд╣реАрдВред рд╕рд┐рд░реНрдл рдЗрд╕рд▓рд┐рдП рдХрд┐ рд╕реЙрд░реНрдЯ рдХреАрдЬрд╝ рдХреЗ рд╕рдорд╛рди рдорд╛рдиреЛрдВ рдХреЗ рд╕рд╛рде, рдРрд╕реЗ рдмреНрд▓реЙрдХ рдХреЗ рдЕрдВрджрд░ рд░рд┐рдХреЙрд░реНрдбреНрд╕ рдХрд╛ рдХреНрд░рдо рдЦреБрдж рддрдп рдирд╣реАрдВ рд╣реЛрддрд╛ рд╣реИред

рдЙрджрд╛рд╕ рдЖрджреЗрд╢ рджреНрд╡рд╛рд░рд╛ ... рд╕реАрдорд╛


рдЖрдЗрдП рдХрд╛рд░реНрдп рдХреЛ рдереЛрдбрд╝рд╛ рд╕рдВрд╢реЛрдзрд┐рдд рдХрд░реЗрдВ - рдПрдХ рдирдпрд╛ рдлрд╝реАрд▓реНрдб рдЬреЛрдбрд╝реЗрдВ рдЬрд┐рд╕рдореЗрдВ рд╣рдо рдЕрдкрдирд╛ рдорд╛рди v + 1 рд▓рд┐рдЦреЗрдВрдЧреЗ:

 ALTER TABLE tbl ADD COLUMN x integer; 

рдХреГрдкрдпрд╛ рдзреНрдпрд╛рди рджреЗрдВ рдХрд┐ рдпрд╣ рдбрд┐рдЬрд╝рд╛рдЗрди рд▓рдЧрднрдЧ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ, рдмрд┐рдирд╛ рдкреВрд░реА рддрд╛рд▓рд┐рдХрд╛ рдХреЛ рд▓рд┐рдЦреЗред рд▓реЗрдХрд┐рди рдЕрдЧрд░ рдЖрдк рдПрдХ DEFAULT рдорд╛рди рдЬреЛрдбрд╝рддреЗ рд╣реИрдВ, рддреЛ - рдХреЗрд╡рд▓ 11 рд╡реЗрдВ рд╕рдВрд╕реНрдХрд░рдг рд╕реЗ рд╢реБрд░реВ рд╣реЛрддрд╛ рд╣реИ ред

рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдХрдбрд╝рд╡реЗ рдЕрдиреБрднрд╡ рд╕реЗ рд╕рд┐рдЦрд╛рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЪрд▓реЛ рддреБрд░рдВрдд рдПрдХ рд╕реВрдЪрдХрд╛рдВрдХ рдмрдирд╛рддреЗ рд╣реИрдВ рдЬрд┐рд╕рдореЗрдВ рдХреЗрд╡рд▓ рдЕрдирдзрд┐рдХреГрдд рдкреНрд░рд╡рд┐рд╖реНрдЯрд┐рдпрд╛рдБ рд░рд╣реЗрдВрдЧреА:

 CREATE INDEX CONCURRENTLY ON tbl(k, v) WHERE x IS NULL; 

CONCURRENTLY рдЗрдВрдбреЗрдХреНрд╕ рддрд╛рд▓рд┐рдХрд╛ рдХреЗ рд╕рд╛рде рд░реАрдб-рд░рд╛рдЗрдЯ рдХрд╛рдо рдХреЛ рдмреНрд▓реЙрдХ рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ, рдЬрдмрдХрд┐ рдпрд╣ рдзреАрд░реЗ-рдзреАрд░реЗ рдПрдХ рд╡рд┐рд╢рд╛рд▓ рдбреЗрдЯрд╛рд╕реЗрдЯ рдкрд░ рднреА рд░реЛрд▓ рдХрд░рддрд╛ рд╣реИред

рдЕрдм рд╡рд┐рдЪрд╛рд░ рдпрд╣ рд╣реИ рдХрд┐ "рдЗрд╕ рд╕реВрдЪрдХрд╛рдВрдХ рд╕реЗ рд╣рд░ рдмрд╛рд░ рдХреЗрд╡рд▓ рдкрд╣рд▓реЗ рд╣рдЬрд╛рд░ рд░рд┐рдХреЙрд░реНрдб рдХрд╛ рдЪрдпрди рдХрд░реЗрдВ" :

 UPDATE tbl T SET x = Tv + 1 FROM ( SELECT k, v FROM tbl WHERE k BETWEEN 'q' AND 'z' AND x IS NULL ORDER BY k, v LIMIT 1000 --   OFFSET! ) S WHERE (Tk, Tv) = (Sk, Sv) AND Tx IS NULL; 


[рд╕реНрдкрд╖реНрдЯреАрдХрд░рдг рдкрд░ рджреЗрдЦреЗрдВ редensor.ru]

рдкрд╣рд▓реЗ рд╕реЗ рдмрд╣реБрдд рдмреЗрд╣рддрд░ - рдкреНрд░рддреНрдпреЗрдХ рд╡реНрдпрдХреНрддрд┐рдЧрдд рд▓реЗрдирджреЗрди рдХреА рдЕрд╡рдзрд┐ рдЕрдм рд▓рдЧрднрдЧ 6 рдЧреБрдирд╛ рдХрдо рд╣реИред

рд▓реЗрдХрд┐рди рдлрд┐рд░ рджреЗрдЦрддреЗ рд╣реИрдВ рдХрд┐ 200 рд╡реЗрдВ рдкреБрдирд░рд╛рд╡реГрддреНрддрд┐ рдХреА рдпреЛрдЬрдирд╛ рдХреНрдпрд╛ рд╣реЛрдЧреА:

 Update on tbl t (actual time=530.591..530.591 rows=0 loops=1) Buffers: shared hit=789337 read=1 dirtied=1 

рд╕рдордп рдлрд┐рд░ рд╕реЗ рдЦрд░рд╛рдм рд╣реЛ рдЧрдпрд╛ (рдХреЗрд╡рд▓ 25%, рд╣рд╛рд▓рд╛рдВрдХрд┐), рдФрд░ рдмрдлрд╝рд░реНрд╕ рдореЗрдВ рд╡реГрджреНрдзрд┐ рд╣реБрдИ - рд▓реЗрдХрд┐рди рдХреНрдпреЛрдВ?
рддрдереНрдп рдпрд╣ рд╣реИ рдХрд┐ PostgreSQL рдореЗрдВ MVCC рд╕реВрдЪрдХрд╛рдВрдХ рдореЗрдВ "рдореГрдд рдЖрддреНрдорд╛рдУрдВ" рдХреЛ рдЫреЛрдбрд╝ рджреЗрддрд╛ рд╣реИ - рдкрд╣рд▓реЗ рд╕реЗ рдЕрдкрдбреЗрдЯ рдХрд┐рдП рдЧрдП рд░рд┐рдХреЙрд░реНрдб рдХреЗ рд╕рдВрд╕реНрдХрд░рдг, рдЕрдм рд╕реВрдЪрдХрд╛рдВрдХ рдХреЗ рд▓рд┐рдП рдЙрдкрдпреБрдХреНрдд рдирд╣реАрдВ рд╣реИред рдпрд╣реА рд╣реИ, 200 рд╡реЗрдВ рдкреБрдирд░рд╛рд╡реГрддреНрддрд┐ рдкрд░ рдХреЗрд╡рд▓ рдкрд╣рд▓реЗ 1000 рд░рд┐рдХреЙрд░реНрдб рд▓реЗрддреЗ рд╣реБрдП, рд╣рдо рдЕрднреА рднреА рд╕реНрдХреИрди рдХрд░рддреЗ рд╣реИрдВ , рднрд▓реЗ рд╣реА рдмрд╛рдж рдореЗрдВ, рд╣рдо рдкрд╣рд▓реЗ рд╕реЗ рдмрджрд▓реЗ рдЧрдП рдЯреНрдпреВрдкрд▓реНрд╕ рдХреЗ рдкрд┐рдЫрд▓реЗ 199K рд╕рдВрд╕реНрдХрд░рдгреЛрдВ рдХреЛ рдЫреЛрдбрд╝ рджреЗрддреЗ рд╣реИрдВред

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

рдЦрдВрдб рджреНрд╡рд╛рд░рд╛ рдЕрджреНрдпрддрди


рджрд░рдЕрд╕рд▓, рд╣рдо "1000 рд░рд┐рдХреЙрд░реНрдб" рдХреЗ рдЗрд╕ рдореВрд▓реНрдп рд╕реЗ рдХреНрдпреЛрдВ рдЬреБрдбрд╝реЗ рд╣реБрдП рд╣реИрдВ? рдЖрдЦрд┐рд░рдХрд╛рд░, рд╣рдорд╛рд░реЗ рдкрд╛рд╕ 1000 рдпрд╛ рдХреБрдЫ рдЕрдиреНрдп рд╡рд┐рд╢рд┐рд╖реНрдЯ рд╕рдВрдЦреНрдпрд╛ рдЪреБрдирдиреЗ рдХрд╛ рдХреЛрдИ рдХрд╛рд░рдг рдирд╣реАрдВ рд╣реИ ред рд╣рдо рд╕рд┐рд░реНрдл рд╕рдВрдкреВрд░реНрдг рдбреЗрдЯрд╛рд╕реЗрдЯ рдХреЛ рдХреЗрд╡рд▓ "рдХрдЯ" рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рдереЗ, рдЬрд░реВрд░реА рдирд╣реАрдВ рдХрд┐ рд╕рдорд╛рди, рдЕрд╕рдорд╛рди рдЦрдВрдб рд╣реЛрдВ - рдЗрд╕рд▓рд┐рдП рдЕрдкрдиреЗ рдореМрдЬреВрджрд╛ рд╕реВрдЪрдХрд╛рдВрдХ рдХрд╛ рдЙрдкрдпреЛрдЧ рдЕрдкрдиреЗ рдЗрдЪреНрдЫрд┐рдд рдЙрджреНрджреЗрд╢реНрдп рдХреЗ рд▓рд┐рдП рдХрд░реЗрдВред

рдПрдХ рдЕрдиреБрдХреНрд░рдорд┐рдд рдЬреЛрдбрд╝реА (k, v) рд╣рдорд╛рд░реЗ рдХрд╛рд░реНрдп рдХреЗ рд▓рд┐рдП рдЙрддреНрдХреГрд╖реНрдЯ рд╣реИред рдЖрдЗрдП рдПрдХ рдХреНрд╡реЗрд░реА рдмрдирд╛рдПрдВ рддрд╛рдХрд┐ рдпрд╣ рдЕрдВрддрд┐рдо рд╕рдВрд╕рд╛рдзрд┐рдд рдЬреЛрдбрд╝реА рдкрд░ рдирд┐рд░реНрдорд╛рдг рдХрд░ рд╕рдХреЗ:

 WITH kv AS ( SELECT k, v FROM tbl WHERE (k, v) > ($1, $2) AND k BETWEEN 'q' AND 'z' AND x IS NULL ORDER BY k, v LIMIT 1 ) , upd AS ( UPDATE tbl T SET x = Tv + 1 WHERE (Tk, Tv) = (TABLE kv) AND Tx IS NULL RETURNING k, v ) TABLE upd LIMIT 1; 

рдкрд╣рд▓реА рдкреБрдирд░рд╛рд╡реГрддреНрддрд┐ рдореЗрдВ, рдХреНрд╡реЗрд░реА рдкреИрд░рд╛рдореАрдЯрд░ рдХреЛ "рд╢реВрдиреНрдп" рдорд╛рди ('', 0) рдкрд░ рд╕реЗрдЯ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдкрд░реНрдпрд╛рдкреНрдд рд╣реИ, рдФрд░ рдкреНрд░рддреНрдпреЗрдХ рдЕрдЧрд▓реЗ рдкреБрдирд░рд╛рд╡реГрддреНрддрд┐ рдХреЗ рд▓рд┐рдП рд╣рдо рдкрд┐рдЫрд▓реА рдХреНрд╡реЗрд░реА рдХрд╛ рдкрд░рд┐рдгрд╛рдо рд▓реЗрддреЗ рд╣реИрдВред


[рд╕реНрдкрд╖реНрдЯреАрдХрд░рдг рдкрд░ рджреЗрдЦреЗрдВ редensor.ru]

рд▓реЗрди-рджреЗрди / рд▓реЙрдХ рдХрд╛ рд╕рдордп рдПрдХ рдорд┐рд▓реАрд╕реЗрдХрдВрдб рд╕реЗ рдХрдо рд╣реИ, рдкреБрдирд░рд╛рд╡реГрддреНрддрд┐рдпреЛрдВ рдХреА рд╕рдВрдЦреНрдпрд╛ рдореЗрдВ рдХреЛрдИ рдЧрд┐рд░рд╛рд╡рдЯ рдирд╣реАрдВ рд╣реИ, рддрд╛рд▓рд┐рдХрд╛ рдореЗрдВ рд╕рднреА рдбреЗрдЯрд╛ рдХреА рдПрдХ рдкреВрд░реНрдг рдкреНрд░рд╛рд░рдВрднрд┐рдХ рд╕реНрдХреИрди рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИред рдмрд╣реБрдд рдмрдврд╝рд┐рдпрд╛!

рдбрдмреНрд▓рд┐рдВрдХ рдХреЗ рд╕рд╛рде рдЕрдВрддрд┐рдо рд╕рдВрд╕реНрдХрд░рдг рд▓рд╛рдирд╛
 DO $$ DECLARE k text = ''; v integer = 0; BEGIN PERFORM dblink_connect('dbname=' || current_database() || ' port=' || current_setting('port')); --  PREPARED STATEMENT,      PERFORM dblink($q$ PREPARE _q(text, integer) AS WITH kv AS ( SELECT k, v FROM tbl WHERE (k, v) > ($1, $2) AND k BETWEEN 'q' AND 'z' AND x IS NULL ORDER BY k, v LIMIT 1 ) , upd AS ( UPDATE tbl T SET x = Tv + 1 WHERE (Tk, Tv) = (TABLE kv) AND Tx IS NULL RETURNING k, v ) TABLE upd LIMIT 1; $q$); -- ,    LOOP SELECT * INTO k, v FROM dblink($p$EXECUTE _q('$p$ || k || $p$',$p$ || v || $p$)$p$) T(k text, v integer); RAISE NOTICE '(k,v) = (''%'',%)', k, v; --   ,     EXIT WHEN (k, v) IS NULL; END LOOP; PERFORM dblink_disconnect(); END; $$ LANGUAGE plpgsql; 


рдЗрд╕ рдкрджреНрдзрддрд┐ рдХрд╛ рдПрдХ рдЕрддрд┐рд░рд┐рдХреНрдд рд▓рд╛рдн рдХрд┐рд╕реА рднреА рд╕рдордп рдЗрд╕ рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХреЗ рдирд┐рд╖реНрдкрд╛рджрди рдХреЛ рдмрд╛рдзрд┐рдд рдХрд░рдиреЗ рдХреА рдХреНрд╖рдорддрд╛ рд╣реИ, рдФрд░ рдлрд┐рд░ рд╡рд╛рдВрдЫрд┐рдд рдмрд┐рдВрджреБ рд╕реЗ рдлрд┐рд░ рд╕реЗ рд╢реБрд░реВ рдХрд░рдирд╛ рд╣реИред

UPDATE рдореЗрдВ рдЬрдЯрд┐рд▓ рдЧрдгрдирд╛


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

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

рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рд╣рдо рдЕрдкрдиреЗ рдирдП рдлрд╝реАрд▓реНрдб x рдХреЛ рдЙрди рд░рд┐рдХреЙрд░реНрдбреЛрдВ рдХреА рд╕рдВрдЦреНрдпрд╛ рдХреЗ рд╕рд╛рде рдЖрдмрд╛рдж рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ рдЬрд┐рдирдХрд╛ рдореВрд▓реНрдп (k, v) рд╕рдорд╛рди рд╣реИред рдЪрд▓реЛ рдПрдХ "рдЕрд╕реНрдерд╛рдпреА" рддрд╛рд▓рд┐рдХрд╛ рдмрдирд╛рддреЗ рд╣реИрдВ, рдЬрд┐рд╕рдХреА рдкреАрдврд╝реА рдЕрддрд┐рд░рд┐рдХреНрдд рддрд╛рд▓реЗ рдирд╣реАрдВ рд▓рдЧрд╛рддреА рд╣реИ:

 CREATE TABLE tmp AS SELECT k, v, count(*) x FROM tbl GROUP BY 1, 2; CREATE INDEX ON tmp(k, v); 

рдЕрдм рд╣рдо рдЗрд╕ рддрд╛рд▓рд┐рдХрд╛ рдХреЗ рдЕрдиреБрд╕рд╛рд░ рдКрдкрд░ рд╡рд░реНрдгрд┐рдд рдореЙрдбрд▓ рдХреЗ рдЕрдиреБрд╕рд╛рд░ рд▓рдХреНрд╖реНрдп рдХреЛ рдЕрджреНрдпрддрди рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:

 UPDATE tbl T SET x = Sx FROM tmp S WHERE (Tk, Tv) = (Sk, Sv) AND (Sk, Sv) = ($1, $2); 

рдЬреИрд╕рд╛ рдХрд┐ рдЖрдк рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ, рдХреЛрдИ рдЬрдЯрд┐рд▓ рдЧрдгрдирд╛ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИред

рдмрд╕ рдмрд╛рдж рдореЗрдВ рд╕рд╣рд╛рдпрдХ рддрд╛рд▓рд┐рдХрд╛ рдХреЛ рд╣рдЯрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдпрд╛рдж рд░рдЦреЗрдВред

Source: https://habr.com/ru/post/hi481610/


All Articles