PostgreSQL Antipatterns: рдПрдХ рджреБрд░реНрд▓рдн рд░рд┐рдХреЙрд░реНрдб JOIN рдХреЗ рдордзреНрдп рддрдХ рдкрд╣реБрдВрдЪ рдЬрд╛рдПрдЧрд╛

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

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


рдЕрдкрдиреЗ рдЖрдк рд╕реЗ, рддрд╛рд▓рд┐рдХрд╛рдУрдВ рдХреЛ рдЬреЛрдбрд╝рдирд╛ рди рддреЛ рд╣рд╛рдирд┐рдХрд╛рд░рдХ рд╣реИ рдФрд░ рди рд╣реА рдЙрдкрдпреЛрдЧреА рд╣реИ - рдпрд╣ рд╕рд┐рд░реНрдл рдПрдХ рдЙрдкрдХрд░рдг рд╣реИ, рд▓реЗрдХрд┐рди рдЖрдкрдХреЛ рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред

рдУрд╡рд░рд╕рд╛рдЗрдЯ рдЧреНрд░реБрдкрд┐рдВрдЧ


рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рдПрдХ рдмрд╣реБрдд рд╕рд░рд▓ рдЙрджрд╛рд╣рд░рдг рд▓реЗрддреЗ рд╣реИрдВред

100 рдкреНрд░рд╡рд┐рд╖реНрдЯрд┐рдпреЛрдВ рдХрд╛ рдПрдХ "рд╢рдмреНрджрдХреЛрд╢" рд╣реИ (рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдпреЗ рд░реВрд╕реА рд╕рдВрдШ рдХреЗ рдХреНрд╖реЗрддреНрд░ рд╣реИрдВ):

CREATE TABLE tbl_dict AS SELECT generate_series(0, 100) k; ALTER TABLE tbl_dict ADD PRIMARY KEY(k); 

... рдФрд░ рдЗрд╕рд╕реЗ рдЬреБрдбрд╝реА рдкреНрд░рддрд┐ 100K рдкреНрд░рд╡рд┐рд╖реНрдЯрд┐рдпреЛрдВ рдореЗрдВ рд╕рдВрдмрдВрдзрд┐рдд "рддрдереНрдпреЛрдВ" рдХреА рдПрдХ рддрд╛рд▓рд┐рдХрд╛ рд╣реИ:

 CREATE TABLE tbl_fact AS SELECT (random() * 100)::integer k , (random() * 1000)::integer v FROM generate_series(1, 100000); CREATE INDEX ON tbl_fact(k); 

рдЕрдм рдЪрд▓реЛ рдкреНрд░рддреНрдпреЗрдХ "рдХреНрд╖реЗрддреНрд░" рдХреЗ рд▓рд┐рдП рдорд╛рдиреЛрдВ рдХреА рд░рд╛рд╢рд┐ рдХреА рдЧрдгрдирд╛ рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░реЗрдВред

рдЬреИрд╕рд╛ рд╕реБрдирд╛ рдЬрд╛рддрд╛ рд╣реИ, рд╡реИрд╕рд╛ рд╣реА рд▓рд┐рдЦрд╛ рдЬрд╛рддрд╛ рд╣реИ


 SELECT dk , sum(fv) FROM tbl_fact f NATURAL JOIN tbl_dict d GROUP BY 1; 

рдбреЗрдЯрд╛ рдХреЛ рдкрдврд╝рдиреЗ рдореЗрдВ рдХреЗрд╡рд▓ 18% рд╕рдордп рд▓рдЧрддрд╛ рдерд╛, рдмрд╛рдХреА рдХреА рдкреНрд░реЛрд╕реЗрд╕рд┐рдВрдЧ рд╣реЛрддреА рдереА:


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

рдФрд░ рд╕рднреА рдХреНрдпреЛрдВрдХрд┐ рд╣реИрд╢ рдЬреЙрдЗрди рдФрд░ рд╣реИрд╢ рдПрдЧреНрд░реАрдЧреЗрдЯ рдХреЛ рд▓рд┐рдВрдХ рдЯреЗрдмрд▓ рдХреЗ рдХреНрд╖реЗрддреНрд░ рджреНрд╡рд╛рд░рд╛ рд╕рдореВрд╣ рдХреА рд╣рдорд╛рд░реА рдЗрдЪреНрдЫрд╛ рдХреЗ рдХрд╛рд░рдг рдкреНрд░рддреНрдпреЗрдХ 100K рд░рд┐рдХреЙрд░реНрдб рдХреЛ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд░рдирд╛ рдерд╛ред

рд╣рдо рд╕рд░рд▓рддрд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ


рд▓реЗрдХрд┐рди рдЗрд╕ рдХреНрд╖реЗрддреНрд░ рдХрд╛ рдорд╛рди рдХреБрд▓ рддрд╛рд▓рд┐рдХрд╛ рдореЗрдВ рдХреНрд╖реЗрддреНрд░ рдХреЗ рдореВрд▓реНрдп рдХреЗ рдмрд░рд╛рдмрд░ рд╣реИ! рдпрд╣реА рд╣реИ, рдХреЛрдИ рднреА рд╣рдореЗрдВ рдкрд╣рд▓реЗ "рддрдереНрдпреЛрдВ" рдХреЛ рд╕рдореВрд╣реАрдХреГрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдкрд░реЗрд╢рд╛рди рдХрд░рддрд╛ рд╣реИ , рдФрд░ рдЙрд╕рдХреЗ рдмрд╛рдж рд╣реА рдХреЛрдИ рд╕рдВрдмрдВрдз рдмрдирд╛рддрд╛ рд╣реИ :

 SELECT dk , f.sum FROM ( SELECT k , sum(v) FROM tbl_fact GROUP BY 1 ) f NATURAL JOIN tbl_dict d; 


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

рдмреЗрд╢рдХ, рд╡рд┐рдзрд┐ рд╕рд╛рд░реНрд╡рднреМрдорд┐рдХ рдирд╣реАрдВ рд╣реИ, рд▓реЗрдХрд┐рди "рд╕рд╛рдорд╛рдиреНрдп рдЬреЙрдЗрди" рдХреЗ рд╣рдорд╛рд░реЗ рдорд╛рдорд▓реЗ рдХреЗ рд▓рд┐рдП , рд╕рдордп рдХрд╛ рд▓рд╛рдн рдЕрдиреБрд░реЛрдз рдХреЗ рдиреНрдпреВрдирддрдо рд╕рдВрд╢реЛрдзрди рдХреЗ рд╕рд╛рде 2 рдЧреБрдирд╛ рд╣реИ - рдмрд╕ "nullified" рд╣реИрд╢ рдЬреЙрдЗрди рдХреЗ рдХрд╛рд░рдг, рдЬрд┐рд╕реЗ 100% рдкреНрд░рд╡рд┐рд╖реНрдЯрд┐рдпреЛрдВ рдХреЗ рдмрдЬрд╛рдп рдХреЗрд╡рд▓ 100 рдкреНрд░рд╡рд┐рд╖реНрдЯрд┐рдпрд╛рдВ рдкреНрд░рд╛рдкреНрдд рд╣реБрдИрдВред

рдЕрд╕рдорд╛рди рд╕реНрдерд┐рддрд┐рдпрд╛рдБ


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

рдПрдХ рдЫреЛрдЯреА рд▓реЗрдХрд┐рди рдмрд╣реБрдд рдорд╣рддреНрд╡рдкреВрд░реНрдг рдЯрд┐рдкреНрдкрдгреА: рднрд▓реЗ рд╣реА рд▓рдХреНрд╖реНрдп рдХрд╛рд░реНрдп рдХреЗ "рд▓рд╛рдЧреВ" рдЬреНрдЮрд╛рди рдХреЗ рдЖрдзрд╛рд░ рдкрд░, рд╣рдо рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдЬрд╛рдирддреЗ рд╣реИрдВ рдХрд┐ рд╢рд░реНрддреЛрдВ рдХреЛ рдкрд╣рд▓реЗ рддрд╛рд▓рд┐рдХрд╛ рдкрд░ рд╕рдВрддреБрд╖реНрдЯ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ - рд▓рдЧрднрдЧ рд╣рдореЗрд╢рд╛ (рдирд┐рд╢реНрдЪрд┐рддрддрд╛ рдХреЗ рд▓рд┐рдП - 3: 4), рдФрд░ рджреВрд╕рд░реЗ рдкрд░ - рдмрд╣реБрдд рдХрдо (1: 8) )ред

рд╣рдо рдореБрдЦреНрдп рдФрд░ рдкрд╣рд▓реЗ рд╕рд╣рд╛рдпрдХ рддрд╛рд▓рд┐рдХрд╛рдУрдВ рд╕реЗ рдкрд╣рдЪрд╛рди рдХреЗ рд╕рд╛рде 100 рдкрд╣рд▓реЗ рд░рд┐рдХреЙрд░реНрдб рдЖрдИрдбреА рд╕реЗ рднреА рдЪрдпрди рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ, рдЬрд┐рд╕рдХреЗ рд▓рд┐рдП рд╕рднреА рддрд╛рд▓рд┐рдХрд╛рдУрдВ рдкрд░ рд╕реНрдерд┐рддрд┐рдпрд╛рдВ рд╕рдВрддреБрд╖реНрдЯ рд╣реИрдВ ред рддрд╛рд▓рд┐рдХрд╛рдУрдВ рдореЗрдВ рд╕рднреА рд░рд┐рдХреЙрд░реНрдб, рд╣рдореЗрдВ рдлрд┐рд░ рд╕реЗ 100K рдкрд░ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред

рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдЬрдирд░реЗрдЯрд░
 CREATE TABLE base( id integer PRIMARY KEY , val integer ); INSERT INTO base SELECT id , (random() * 1000)::integer FROM generate_series(1, 100000) id; CREATE TABLE ext1( id integer PRIMARY KEY , conda boolean ); INSERT INTO ext1 SELECT id , (random() * 4)::integer <> 0 -- 3:4 FROM generate_series(1, 100000) id; CREATE TABLE ext2( id integer PRIMARY KEY , condb boolean ); INSERT INTO ext2 SELECT id , (random() * 8)::integer = 0 -- 1:8 FROM generate_series(1, 100000) id; 

рдЬреИрд╕рд╛ рд╕реБрдирд╛ рдЬрд╛рддрд╛ рд╣реИ, рд╡реИрд╕рд╛ рд╣реА рд▓рд┐рдЦрд╛ рдЬрд╛рддрд╛ рд╣реИ


 SELECT base.* , ext1.* FROM base NATURAL JOIN ext1 NATURAL JOIN ext2 WHERE id % 2 = 0 AND conda AND condb ORDER BY base.id LIMIT 100; 


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

рд╢рдмреНрджреЛрдВ рдореЗрдВ рдирдХрд╛рд░рд╛рддреНрдордХ рд╕рдордп
рдЗрддрдиреЗ рд╕рд╛рд░реЗ рдЪрдХреНрд░ рдХреБрдЫ рдиреЛрдбреНрд╕ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдЪрд▓реЗ рдЧрдП рд╣реИрдВ рдХрд┐ рдХреБрдЫ рдХреА рдЧреЛрд▓рд╛рдИ рддреНрд░реБрдЯрд┐рдпреЛрдВ рдХреЛ рднреА minuses рдореЗрдВ рд╕рдВрдЪрд╛рд▓рд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред рдпреЛрдЬрдирд╛рдУрдВ рдореЗрдВ рдЗрд╕реА рддрд░рд╣ рдХреА рдХрд▓рд╛рдХреГрддрд┐рдпреЛрдВ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдореИрдВ PGConf.Russia рдкрд░ рдмрд╛рдд рдХрд░реВрдВрдЧрд╛ ред

200ms рдФрд░ рдЕрдзрд┐рдХ 2GB рдбреЗрдЯрд╛ рдкрдВрдк - 100 рд░рд┐рдХреЙрд░реНрдб рдХреЗ рд▓рд┐рдП рдмрд╣реБрдд рдЕрдЪреНрдЫрд╛ рдирд╣реАрдВ рд╣реИ!

рд╣рдо рд╕рд░рд▓рддрд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ


рддреНрд╡рд░рдг рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╣рдо рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рддрд░реАрдХреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ:

  1. рд╢реБрд░реВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо рд╕рдордЭрддреЗ рд╣реИрдВ рдХрд┐ рд▓рд┐рдВрдХ рдЯреЗрдмрд▓ рдХреЗ рд▓рд┐рдП рд╕рднреА рд╢рд░реНрддреЛрдВ рдХреА рдЬрд╛рдВрдЪ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдпрд╣ рд╣рдорд╛рд░реЗ рд▓рд┐рдП рд╕рдордЭ рдореЗрдВ рдЖрддрд╛ рд╣реИ рдЬрдм рдореБрдЦреНрдп рддрд╛рд▓рд┐рдХрд╛ рдХреЗ рд▓рд┐рдП рд╢рд░реНрддреЗрдВ рдкреВрд░реА рд╣реЛрддреА рд╣реИрдВ (рдпрд╣рд╛рдВ рддрдХ тАЛтАЛрдХрд┐ рдЖрдИрдбреА рдХреЗ рд▓рд┐рдП)ред
  2. рдЖрдЙрдЯрдкреБрдЯ рдХреЛ рдЖрдзрд╛рд░ рджреНрд╡рд╛рд░рд╛ рд╣рд▓ рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред рдФрд░ рдЗрд╕рдХреЗ рд▓рд┐рдП, рдЗрд╕ рддрд╛рд▓рд┐рдХрд╛ рдХреА рдкреНрд░рд╛рдердорд┐рдХ рдХреБрдВрдЬреА рд╣рдорд╛рд░реЗ рд▓рд┐рдП рдПрдХрджрдо рд╕рд╣реА рд╣реИ!
  3. рд╣рдореЗрдВ ext2 рд╕реЗ рдбреЗрдЯрд╛ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИ, рдФрд░ рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдХреЗрд╡рд▓ рд╕реНрдерд┐рддрд┐ рдХреЛ рд╕рддреНрдпрд╛рдкрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдЗрд╕рдХрд╛ рдорддрд▓рдм рдпрд╣ рд╣реИ рдХрд┐ рдЗрд╕ рддрд╛рд▓рд┐рдХрд╛ рдХреЗ рд╕рд╛рде рд╕рднреА рдХрд╛рдо рдХреЛ JOIN рд╕реЗ WHERE рдХреЗ рд╣рд┐рд╕реНрд╕реЗ рдореЗрдВ рд╕реБрд░рдХреНрд╖рд┐рдд рд░реВрдк рд╕реЗ рд╣рдЯрд╛рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рдФрд░ рдЬрд╛рдБрдЪ рдХреЗ рд▓рд┐рдП EXISTS рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВ, рдЕрдиреНрдпрдерд╛ рдХреНрдпрд╛ рд╣реЛрдЧрд╛ рдЕрдЧрд░ рдРрд╕рд╛ рдХреЛрдИ рд░рд┐рдХреЙрд░реНрдб рдирд╣реАрдВ рд╣реИ?
  4. рд╣рдореЗрдВ ext1 рд╕реЗ рдХрдо рд╕реЗ рдХрдо рдХреБрдЫ рдбреЗрдЯрд╛ рдкреБрдирд░реНрдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ , рдпрджрд┐ рдЖрдзрд╛рд░ рдФрд░ ext2 рдкрд░ рд╢реЗрд╖ рдЪреЗрдХ рд╕рдлрд▓рддрд╛рдкреВрд░реНрд╡рдХ рдкрд╛рд░рд┐рдд рд╣реЛ ред рдпрд╣реА рд╣реИ, ext1 рдХреЗ рд╕рд╛рде рдХрдиреЗрдХреНрд╢рди рдЖрдзрд╛рд░ / ext2 рдХреЗ рд╕рд╛рде рд╕рднреА рдХрд╛рд░реНрдпреЛрдВ рдХреЗ рдмрд╛рдж рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП, рдЬрд┐рд╕реЗ LATERAL рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдкреНрд░рд╛рдкреНрдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред
  5. рддрд╛рдХрд┐ рдХреНрд╡реЗрд░реА рдкреНрд▓рд╛рдирд░ рдиреЗ N2 рдореЗрдВ рдирд┐рд╣рд┐рдд рд╕рддреНрдпрд╛рдкрди рдХреЛ NIN, "CASE рдХреЗ рддрд╣рдд рдЫрд┐рдкрд╛рдПрдВ" рдЙрдкрдЦрдгреНрдб рдореЗрдВ рдмрджрд▓рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рди рдХреА рд╣реЛред

 SELECT base.* , ext1.* FROM base , LATERAL( --       base SELECT * FROM ext1 WHERE id = base.id AND conda --   LIMIT 1 ) ext1 WHERE CASE WHEN base.id % 2 = 0 THEN EXISTS( --        SELECT NULL FROM ext2 WHERE id = base.id AND condb --   LIMIT 1 ) END ORDER BY base.id --     PK,       LIMIT 100; 


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

рдирд┐рд╡реЗрджрди, рдирд┐рд╕реНрд╕рдВрджреЗрд╣, рдЕрдзрд┐рдХ рдЬрдЯрд┐рд▓ рд╣реЛ рдЧрдпрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рд╕рдордп рдореЗрдВ 13 рдмрд╛рд░ рдЬреАрддрдирд╛ рдФрд░ "рд▓реЛрд▓реБрдкрддрд╛" рдореЗрдВ 350 рдЗрд╕рдХреЗ рд▓рд╛рдпрдХ рд╣реИ!

рдореИрдВ рдЖрдкрдХреЛ рдлрд┐рд░ рд╕реЗ рдпрд╛рдж рджрд┐рд▓рд╛рддрд╛ рд╣реВрдВ рдХрд┐ рд╕рднреА рд╡рд┐рдзрд┐рдпреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рдФрд░ рд╣рдореЗрд╢рд╛ рдирд╣реАрдВ, рд▓реЗрдХрд┐рди рдЬрд╛рдирдирд╛ рдЕрддрд┐-рдЙрдкрдпреЛрдЧреА рдирд╣реАрдВ рд╣реЛрдЧрд╛ред

рдпрд╣ рднреА рджрд┐рд▓рдЪрд╕реНрдк рд╣реЛрдЧрд╛:

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


All Articles