рдЗрд╕ рдкреНрд░рдХреНрд╖реЗрдкрдг рдХрд╛ рд╡рд┐рдЪрд╛рд░ (рдЕрд░реНрдерд╛рддреН "рдкреНрд░рдХреНрд╖реЗрдкрдг") рдЕрдирд╛рдпрд╛рд╕ рдЙрддреНрдкрдиреНрди рд╣реБрдЖред рдХрдВрдкрдиреА рдореЗрдореЛрд░реА-рдбреАрдмреА рдЯрд╛рдЗрдореНрд╕рдЯреЗрди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреА рд╣реИ, рдЬрд┐рд╕рдореЗрдВ рдбреЗрдЯрд╛ рдХреЗ рд╕рд╛рде рдПрдХ рдмрдбрд╝реА рддрд╛рд▓рд┐рдХрд╛, 150 рдорд┐рд▓рд┐рдпрди рд╕реЗ рдЕрдзрд┐рдХ рд░рд┐рдХреЙрд░реНрдб рдФрд░ рд▓рдЧрднрдЧ 15 рдЧрд┐рдЧреНрд╕ рдХреА рдорд╛рддреНрд░рд╛ рд╣реЛрддреА рд╣реИред TimesTen рдиреЗ рд╣рдореЗрд╢рд╛ рдареАрдХ рд╕реЗ рдХрд╛рдо рдХрд┐рдпрд╛, рдорд┐рд▓реАрд╕реЗрдХрдВрдб рдХреЗ рдПрдХ рдорд╛рдорд▓реЗ рдореЗрдВ рдХрд┐рд╕реА рднреА рдЕрдиреБрд░реЛрдз рдХрд╛ рдЬрд╡рд╛рдм рдорд┐рд▓рд╛, рдпрд╣ рд╕рднреА рдХреЗ рд▓рд┐рдП рдЕрдиреБрдХреВрд▓ рдерд╛ред рдПрдХ рджрд┐рди, T10 рдиреЗ рдмрд╣реБрдд рд▓рдВрдмреЗ рд╕рдордп рдХреЗ рдЕрдиреБрд░реЛрдзреЛрдВ рдХрд╛ рдЬрд╡рд╛рдм рджреЗрдирд╛ рд╢реБрд░реВ рдХрд┐рдпрд╛, рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рд╕рдордп 3-5 рд╕реЗрдХрдВрдб рддрдХ рдмрдврд╝ рдЧрдпрд╛ред рддрдХрдиреАрдХреА рд╕рд╣рд╛рдпрддрд╛, рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ, рдПрдХ рд╕рдорд╕реНрдпрд╛ рдкрд░ рдХрд╛рдо рдХрд░рдирд╛ рд╢реБрд░реВ рдХрд┐рдпрд╛, рд▓реЗрдХрд┐рди рд╕рд╛рде рд╣реА рд╣рдордиреЗ рдЦреБрдж рд╕реЗ рдкреВрдЫрд╛ рдХрд┐ рдЯреА 10 рдХрд╛ рдЙрдкрдпреЛрдЧ рдХреНрдпреЛрдВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ рдЖрдк рдбреЗрдЯрд╛рдмреЗрд╕ рдХреЛ рдирд┐рдпрдорд┐рдд рдУрд░реЗрдХрд▓ рдпрд╛ рдЖрд░рдбреАрдмреАрдПрдордПрд╕ рдХреЛ рдкреЛрд╕реНрдЯрдЧреНрд░реЗрдЯ рдХреНрдпреЛрдВ рдирд╣реАрдВ рдХрд░ рд╕рдХрддреЗ?
рдЙрдкрдпреБрдХреНрдд рдкрд░реАрдХреНрд╖рдгреЛрдВ рдХрд╛ рд╕рдВрдЪрд╛рд▓рди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдпрд╣ рдкрддрд╛ рд▓рдЧрд╛рдирд╛ рдЖрд╡рд╢реНрдпрдХ рдерд╛ред рдирддреАрдЬрддрди, рдЗрдВрдЯрд░рдиреЗрдЯ рдкрд░ рдЪрд╛рд░реЛрдВ рдУрд░ рдереЛрдбрд╝реА рдЦреБрджрд╛рдИ рдХреЗ рдмрд╛рдж, рдкрд░реАрдХреНрд╖рдг рдХреЗ рд▓рд┐рдП рдЖрд╡рд╢реНрдпрдХ рдореБрдлреНрдд рд╕реЙрдлреНрдЯрд╡реЗрдпрд░ рдирд╣реАрдВ рдорд┐рд▓рд╛ред рдкрд░рд┐рдгрд╛рдорд╕реНрд╡рд░реВрдк, рдЙрд╕ рджрд┐рди рдПрдХ рдЫреЛрдЯреА рдХрдВрд╕реЛрд▓ рдЙрдкрдпреЛрдЧрд┐рддрд╛ "рдЕрдкрдиреЗ рдШреБрдЯрдиреЛрдВ рдкрд░" рд▓рд┐рдЦреА рдЧрдИ рдереА, рдЬреЛ рд╡рд┐рднрд┐рдиреНрди рдкреНрд░рдХрд╛рд░ рдХреЗ рдкреНрд░рд╢реНрдиреЛрдВ рдХреЗ рд▓рд┐рдП рдбреАрдмреАрдПрдордПрд╕ рд╕реЗ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рд╕рдордп рдХреЛ рдорд╛рдкрддрд╛ рд╣реИ, рдЖрдВрдХрдбрд╝реЗ рдПрдХрддреНрд░ рдХрд░рддрд╛ рд╣реИ, рдФрд░ рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛ рдЗрд╕реЗ рдорд▓реНрдЯреАрдереНрд░реЗрдб рднреА рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ рддрд╛рдХрд┐ рд▓реЛрдб рдкрд░реАрдХреНрд╖рдг рд╕рдмрд╕реЗ рдЕрдзрд┐рдХ рдЙрджреНрджреЗрд╢реНрдп рд╣реЛред
рдкрд░реАрдХреНрд╖рдг рдХреЗ рд▓рд┐рдП, рдкреЛрд╕реНрдЯрдЧреНрд░реИрдмреНрд╕ рдбреАрдмреАрдПрдордПрд╕ рдХрд╛ рдЪрдпрди рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛, рдбреЗрдЯрд╛рдмреЗрд╕ рдореЗрдВ рд╕рдВрдмрдВрдзрд┐рдд рд╕рдВрд░рдЪрдирд╛ рдХреЗ рд╕рд╛рде рдПрдХ рддрд╛рд▓рд┐рдХрд╛ рдмрдирд╛рдИ рдЧрдИ рдереА, рдЬреЛ рдЗрд╖реНрдЯрддрдо рд╕реВрдЪрдХрд╛рдВрдХ рдмрдирд╛рдП рдЧрдП рдереЗ:
CREATE TABLE "public"."numbers" ( "contract" int8 NOT NULL, "account" int8 NOT NULL, "number" int8 NOT NULL, "system_id" int2 NOT NULL, "region_id" int2 NOT NULL, "storage_id" int2 NOT NULL ); CREATE INDEX "ix_contract" ON "public"."numbers" USING btree ("contract"); CREATE UNIQUE INDEX "ix_number" ON "public"."numbers" USING btree ("number"); CREATE INDEX "ix_account" ON "public"."numbers" USING btree ("account");
рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рддрд╛рд▓рд┐рдХрд╛ рднрд░рдирд╛ (100 рдорд┐рд▓рд┐рдпрди рд░рд┐рдХреЙрд░реНрдб рднрд░рдиреЗ рдХрд╛ рд╕рдордп 7 рдШрдВрдЯреЗ рдерд╛):
CREATE OR REPLACE FUNCTION "public"."fill"(_count int8) RETURNS "pg_catalog"."int8" AS $BODY$DECLARE i int8; j int2; _number_start int8; _pa_start int8; _pa int8; _countract int8; BEGIN _number_start:=70000000000; _pa_start:=1000000000000; FOR i IN 0.._count BY 5 LOOP INSERT INTO number(contract,account,number,system_id,region_id,storage_id) VALUES (round(random()*100000000000+100000000000),round(random()*100000000+_pa_start),_number_start+0+i,round(random()*10+1),round(random()*10+101),round(random()*5+1)), (round(random()*100000000000+100000000000),round(random()*100000000+_pa_start),_number_start+1+i,round(random()*10+1),round(random()*10+101),round(random()*5+1)), (round(random()*100000000000+100000000000),round(random()*100000000+_pa_start),_number_start+2+i,round(random()*10+1),round(random()*10+101),round(random()*5+1)), (round(random()*100000000000+100000000000),round(random()*100000000+_pa_start),_number_start+3+i,round(random()*10+1),round(random()*10+101),round(random()*5+1)), (round(random()*100000000000+100000000000),round(random()*100000000+_pa_start),_number_start+4+i,round(random()*10+1),round(random()*10+101),round(random()*5+1)); END LOOP; RETURN 1; END; $BODY$ LANGUAGE 'plpgsql' VOLATILE COST 100 ;
рд╕рдорд╛рдирд╛рдВрддрд░ рдореЗрдВ, рд╡рд┐рднрд┐рдиреНрди рдкреНрд░рдХрд╛рд░ рдХреЗ рдкреНрд░рд╢реНрдиреЛрдВ рдХреЗ рд╕рд╛рде DBMS рдкрд░ рд▓реЛрдб рдХрд╛ рдЕрдиреБрдХрд░рдг рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдХрдВрд╕реЛрд▓ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдмрдирд╛рдпрд╛ рдЧрдпрд╛ рдерд╛ред PostgreSQL рд╕реЗ рдХрдиреЗрдХреНрдЯ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП,
npgsql рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ред
C # рдореЗрдВ рдореБрдЦреНрдп рдХрд╛рд░реНрдпрдХреНрд░рдо рдХрд╛ рдкрд╛рда:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using Npgsql; using System.Xml; using System.IO; using System.Threading; namespace sqlPerformer { class Program { public static Configuration c; public static string config_file = "config.xml"; //public static config config = new config(); public static Performance performance = new Performance(); public static List<Thread> threads = new List<Thread>(); static void Main(string[] args) { //saveConfig(); Console.WindowWidth = 120; loadConfig(); for (int i = 1; i <= Program.c.threads; i++) { Thread thread = new Thread(Program.thread); thread.Start(i); threads.Add(thread); } //Program.thread(); Console.ReadLine(); } public static void thread(object thread_id) { NpgsqlConnection cn = new NpgsqlConnection(); cn.ConnectionString = string.Format("Server={0}; Port={1}; Database={2}; User Id={3}; Password={4};", Program.c.host, Program.c.port, Program.c.database, Program.c.user, Program.c.password); cn.Open(); for (int i = 0; i <= Program.c.count; i++) { foreach (query q in Program.c.queries.query) { NpgsqlCommand cm = new NpgsqlCommand(); cm.Connection = cn; cm.CommandText = q.text; if (!q.status) continue; foreach (parameter p in q.parameters.parameter) { NpgsqlTypes.NpgsqlDbType _temp_type = NpgsqlTypes.NpgsqlDbType.Integer; object _val = null; switch (p.GetType().Name) { case "bigint": _temp_type = NpgsqlTypes.NpgsqlDbType.Bigint; _val = Program.getRandomInt64(((bigint)p).min, ((bigint)p).max); break; case "integer": _temp_type = NpgsqlTypes.NpgsqlDbType.Integer; _val = Program.getRandomInt32(((integer)p).min, ((integer)p).max); break; case "date": _temp_type = NpgsqlTypes.NpgsqlDbType.Timestamp; _val = Program.getRandomDate(((date)p).min, ((date)p).max); break; case "string_line": _temp_type = NpgsqlTypes.NpgsqlDbType.Varchar; _val = Program.getRandomStringLine(((string_line)p).chars, ((string_line)p).max, ((string_line)p).max); break; case "text": _temp_type = NpgsqlTypes.NpgsqlDbType.Text; _val = Program.getRandomText(((text)p).words, ((text)p).max, ((text)p).max); break; } cm.Parameters.Add(p.id, _temp_type); cm.Parameters[p.id].Value = _val; } Program.delay(); lock (Program.performance) { Program.performance.start(q.id, thread_id.ToString()); } cm.ExecuteNonQuery(); lock (Program.performance) { Program.performance.stop(); } } } } public static long getRandomInt64(long min, long max) { return Convert.ToInt64(Math.Round((new Random(unchecked((int)(DateTime.Now.Ticks)))).NextDouble() * (max - min) + min)); } public static int getRandomInt32(int min, int max) { return Convert.ToInt32(Math.Round((new Random(unchecked((int)(DateTime.Now.Ticks)))).NextDouble() * (max - min) + min)); } public static DateTime getRandomDate(DateTime min, DateTime max) { long stamp_min = min.Ticks; long stamp_max = max.Ticks; long stamp_new = Program.getRandomInt64(stamp_min, stamp_max); return (new DateTime(stamp_new)); } public static string getRandomStringLine(string chars, int min, int max) { string retval = ""; Random r = new Random(unchecked((int)(DateTime.Now.Ticks))); for (int i = 1; i <= r.Next(min, max); i++) retval += chars[r.Next(0, chars.Length - 1)]; return retval; } public static string getRandomText(List<string> words, int min, int max) { string retval = ""; Random r = new Random(unchecked((int)(DateTime.Now.Ticks))); for (int i = 1; i <= r.Next(min, max); i++) retval += " " + words[r.Next(0, words.Count - 1)]; return retval.Trim(); } public static void delay() { if (Program.c.delay.status) System.Threading.Thread.Sleep(Program.getRandomInt32(Program.c.delay.min, Program.c.delay.max)); } static void saveConfig() { Program.c = new Configuration("localhost", 5432, "postgres", "postgres"); query q = new query("SELECT * FROM \"public\".\"table\"(?)"); q.parameters.parameter.Add(new bigint(100000000, 200000000)); c.queries.query.Add(q); System.Xml.Serialization.XmlSerializer xs = new System.Xml.Serialization.XmlSerializer(c.GetType()); StreamWriter writer = File.CreateText(Program.config_file); xs.Serialize(writer, c); writer.Flush(); writer.Close(); } static void loadConfig() { System.Xml.Serialization.XmlSerializer xs = new System.Xml.Serialization.XmlSerializer( typeof(Configuration)); StreamReader reader = File.OpenText(Program.config_file); Program.c = (Configuration)xs.Deserialize(reader); reader.Close(); } } }
рдПрдХ XML рдкреНрд░рд╛рд░реВрдк рд╕реЗрдЯрд┐рдВрдЧреНрд╕ рдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ (рдЕрдзрд┐рдХ рд╕рдЯреАрдХ рд░реВрдк рд╕реЗ, XML рдореЗрдВ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдСрдмреНрдЬреЗрдХреНрдЯ рдХрд╛ рдХреНрд░рдорд╛рдВрдХрди):
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Xml; using System.Xml.Serialization; namespace sqlPerformer { [Serializable] public class Configuration { [System.Xml.Serialization.XmlElement()] public string host = "localhost"; [System.Xml.Serialization.XmlElement()] public int port = 5432; [System.Xml.Serialization.XmlElement()] public string user = "postgres"; [System.Xml.Serialization.XmlElement()] public string database = "postgres"; [System.Xml.Serialization.XmlElement()] public string password = "postgres"; [System.Xml.Serialization.XmlElement()] public queries queries = new queries(); [System.Xml.Serialization.XmlElement()] public delay delay = new delay(); [System.Xml.Serialization.XmlElement()] public int threads = 1; [System.Xml.Serialization.XmlElement()] public int count = 1; public Configuration() { } public Configuration(string host, int port, string user, string password) { this.host = host; this.port = port; this.user = user; this.password = password; } } [Serializable] public class queries { [System.Xml.Serialization.XmlElement()] public List<query> query = new List<query>(); public queries() { } } [Serializable] public class query { [System.Xml.Serialization.XmlAttribute()] public bool status = false; [System.Xml.Serialization.XmlAttribute()] public string id = ""; [System.Xml.Serialization.XmlElement()] public string text = ""; [System.Xml.Serialization.XmlElement()] public parameters parameters = new parameters(); public query() { } public query(string text) { this.text = text; } } [Serializable] public class parameters { [System.Xml.Serialization.XmlElement()] public List<parameter> parameter = new List<parameter>(); public parameters() { } } [Serializable] [System.Xml.Serialization.XmlInclude(typeof(bigint))] [System.Xml.Serialization.XmlInclude(typeof(integer))] [System.Xml.Serialization.XmlInclude(typeof(string_line))] [System.Xml.Serialization.XmlInclude(typeof(text))] [System.Xml.Serialization.XmlInclude(typeof(date))] public abstract class parameter { [System.Xml.Serialization.XmlAttribute()] public string id = ""; public parameter() { } } [Serializable] public class bigint : parameter { [System.Xml.Serialization.XmlElement()] public long min = 0; [System.Xml.Serialization.XmlElement()] public long max = 0; public bigint() { } public bigint(long min, long max) { this.min = min; this.max = max; } } [Serializable] public class integer : parameter { [System.Xml.Serialization.XmlElement()] public int min = 0; [System.Xml.Serialization.XmlElement()] public int max = 0; public integer() { } public integer(int min, int max) { this.min = min; this.max = max; } } [Serializable] public class date : parameter { [System.Xml.Serialization.XmlElement()] public DateTime min = DateTime.Now; [System.Xml.Serialization.XmlElement()] public DateTime max = DateTime.Now; public date() { } public date(DateTime min, DateTime max) { this.min = min; this.max = max; } } [Serializable] public class string_line : parameter { [System.Xml.Serialization.XmlElement()] public string chars = "qwertyuiopasdfghjklzxcvbnm"; [System.Xml.Serialization.XmlElement()] public int min = 2; [System.Xml.Serialization.XmlElement()] public int max = 10; public string_line() { } public string_line(string chars, int min, int max) { this.chars = chars; this.min = min; this.max = max; } } [Serializable] public class text : parameter { [System.Xml.Serialization.XmlElement()] public List<string> words = new List<string>() { "word1", "word2" }; [System.Xml.Serialization.XmlElement()] public int min = 2; [System.Xml.Serialization.XmlElement()] public int max = 10; public text() { } public text(List<string> words, int min, int max) { this.words = words; this.min = min; this.max = max; } } [Serializable] public class delay { [System.Xml.Serialization.XmlAttribute()] public bool status = false; [System.Xml.Serialization.XmlElement()] public int min = 10; [System.Xml.Serialization.XmlElement()] public int max = 100; } }
рдкреНрд░рджрд░реНрд╢рди рдХреЛ рдорд╛рдкрдиреЗ рдХреЗ рд▓рд┐рдП, рдкреНрд░рджрд░реНрд╢рди рд╡рд░реНрдЧ рдмрдирд╛рдпрд╛ рдЧрдпрд╛ рдерд╛:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Diagnostics; namespace sqlPerformer { class Performance { public Stopwatch sw = new Stopwatch(); public Dictionary<string, stat> stat = new Dictionary<string, stat>(); public string current_id = ""; public void start(string id, string thread_id) { this.sw.Reset(); this.current_id = thread_id + "-" + id; if (!this.stat.ContainsKey(this.current_id)) { this.stat.Add(this.current_id, new stat()); } this.sw.Start(); } public void stop() { this.sw.Stop(); addTick(); } public void addTick() { this.stat[this.current_id].add(this.sw.ElapsedTicks); Console.Clear(); foreach (KeyValuePair<string, stat> k in this.stat) Console.WriteLine(string.Format("{0}\tCount: {1}\tAverage: {2:#0.00}\tMin: {3:#0.00}\tMax: {4:#0.00}\tTotal: {5:#}" , k.Key , k.Value.count , k.Value.timeAvg , k.Value.timeMin , k.Value.timeMax , k.Value.timeTotal )); } } public class stat { public Int64 count = 0; public double timeTotal = 0; public double timeLast = 0; public double timeMin = 9999999; public double timeMax = 0; public double timeAvg = 0; public stat() { } public void add(long ticks) { this.count++; this.timeLast = ticks / 10000000.0; this.timeTotal += this.timeLast; this.timeAvg = this.timeTotal / this.count; this.timeMin = Math.Min(this.timeLast, this.timeMin); this.timeMax = Math.Max(this.timeLast, this.timeMax); } } }
рдПрдХ рдкрд░реАрдХреНрд╖рдг рд╕рд╛рдЗрдЯ рдХреЗ рд░реВрдк рдореЗрдВ, 2 рдЧреАрдЧрд╛ рд░реИрдо, рдПрдХ Core2Duo рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдФрд░ рдмреНрд░реЗрдХ рд╕реНрдХреНрд░реВ рдХреЗ рд╕рд╛рде рдПрдХ рдХрд╛рд░реНрдп рдХреЗрдВрджреНрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ред рдкрд░рд┐рдгрд╛рдо рдЖрд╢реНрдЪрд░реНрдпрдЬрдирдХ рдереЗ, 50 рдереНрд░реЗрдбреНрд╕ рдкрд░, рдФрд╕рдд рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ 8-10 рдХреЗ рдХреНрд╖реЗрддреНрд░ рдореЗрдВ рдереА, рдЕрдзрд┐рдХрддрдо 30 рдорд┐рд▓реАрд╕реЗрдХрдВрдб рддрдХ, рд▓реЗрдХрд┐рди рдбрд┐рд╕реНрдХ рднрд╛рд░реА рд░реВрдк рд╕реЗ рднрд░реА рд╣реБрдИ рд╣реИред рдпрд╣ рд╕реНрдкрд╖реНрдЯ рд╣реИ рдХрд┐ рдЧрдВрднреАрд░ рдЙрдкрдХрд░рдгреЛрдВ рдкрд░ рдпреЗ рдореВрд▓реНрдп рдмрд╣реБрдд рдХрдо рд╣реЛрдВрдЧреЗред рд▓реЗрдХрд┐рди рдХреБрдЫ рдФрд░ рдкреНрд░рд╕рдиреНрди рд╣реИ - рдЬрдм рдПрдХ рдмрдбрд╝реА рддрд╛рд▓рд┐рдХрд╛ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рдбреАрдмреАрдПрдордПрд╕ рдХрд╛рдлреА рдкрд░реНрдпрд╛рдкреНрдд рд░реВрдк рд╕реЗ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдХрд░рддрд╛ рд╣реИред
рд╕рд┐рджреНрдзрд╛рдВрдд рд░реВрдк рдореЗрдВ, рдХреЛрдИ рднреА рдбреЗрдЯрд╛ рд▓реЛрдб рдФрд░ рдХрд┐рд╕реА рднреА рд╕рдВрдЦреНрдпрд╛ рдореЗрдВ рддрд╛рд▓рд┐рдХрд╛рдУрдВ рдХреЗ рд╕рд╛рде, рдХрд┐рд╕реА рднреА рдбреЗрдЯрд╛рдмреЗрд╕ рдХреЛ рд▓реЛрдб рдкрд░реАрдХреНрд╖рдг рдХреЗ рд▓рд┐рдП рдЗрд╕ рдХрд╛рд░реНрдпрдХреНрд░рдо рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рд╕реЗ рд░реЛрдХрддрд╛ рд╣реИред