{"id":36704,"date":"2019-10-31T22:13:15","date_gmt":"2019-10-31T19:13:15","guid":{"rendered":"https:\/\/prohoster.info\/blog\/optimizatsiya-zaprosov-bazy-dannyh-na-primere-b2b-servisa-dlya-stroitelej\/"},"modified":"2019-10-31T22:13:15","modified_gmt":"2019-10-31T19:13:15","slug":"optimizatsiya-zaprosov-bazy-dannyh-na-primere-b2b-servisa-dlya-stroitelej","status":"publish","type":"post","link":"https:\/\/prohoster.info\/pl\/blog\/administrirovanie\/optimizatsiya-zaprosov-bazy-dannyh-na-primere-b2b-servisa-dlya-stroitelej","title":{"rendered":"Optymalizacja zapyta\u0144 bazy danych na przyk\u0142adzie us\u0142ugi B2B dla budowniczych","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p>Jak zwi\u0119kszy\u0107 liczb\u0119 zapyta\u0144 do bazy danych dziesi\u0119ciokrotnie, nie przechodz\u0105c na wydajniejszy serwer, i jednocze\u015bnie zachowa\u0107 funkcjonalno\u015b\u0107 systemu? Opowiem, jak walczyli\u015bmy z spadkiem wydajno\u015bci naszej bazy danych, jak optymalizowali\u015bmy zapytania SQL, aby obs\u0142ugiwa\u0107 jak najwi\u0119cej u\u017cytkownik\u00f3w, nie zwi\u0119kszaj\u0105c koszt\u00f3w zasob\u00f3w obliczeniowych.<br \/>\n<noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><br \/>\nTworz\u0119 us\u0142ug\u0119 do zarz\u0105dzania procesami biznesowymi w firmach budowlanych. Wsp\u00f3\u0142pracujemy z oko\u0142o 3 tysi\u0105cami firm. Ponad 10 tysi\u0119cy os\u00f3b codziennie korzysta z naszego systemu przez 4-10 godzin. Rozwi\u0105zuje on r\u00f3\u017cne problemy zwi\u0105zane z planowaniem, powiadamianiem, ostrzeganiem, walidowaniem\u2026 U\u017cywamy PostgreSQL 9.6. W naszej bazie danych znajduje si\u0119 oko\u0142o 300 tabel, a ka\u017cdego dnia dociera do niej do 200 mln zapyta\u0144 (10 tysi\u0119cy r\u00f3\u017cnych). \u015arednio mamy 3-4 tysi\u0105ce zapyta\u0144 na sekund\u0119, a w najbardziej aktywnych momentach ponad 10 tysi\u0119cy zapyta\u0144 na sekund\u0119. Wi\u0119kszo\u015b\u0107 zapyta\u0144 to OLAP. Dodania, modyfikacje i usuni\u0119cia s\u0105 du\u017co rzadziej, co oznacza, \u017ce obci\u0105\u017cenie OLTP jest stosunkowo ma\u0142e. Wszystkie te liczby podaj\u0119, aby mogli Pa\u0144stwo oceni\u0107 skal\u0119 naszego projektu i zrozumie\u0107, jak nasza wiedza mo\u017ce by\u0107 dla Pa\u0144stwa przydatna.<\/p>\n<h3>Obraz pierwszy. Liryczny<\/h3>\n<p>\nGdy rozpoczynali\u015bmy rozw\u00f3j, nie zastanawiali\u015bmy si\u0119 szczeg\u00f3lnie nad tym, jakie obci\u0105\u017cenie spadnie na baz\u0119 danych i co zrobimy, je\u015bli serwer przestanie dzia\u0142a\u0107. Podczas projektowania bazy danych kierowali\u015bmy si\u0119 og\u00f3lnymi zaleceniami i starali\u015bmy si\u0119 nie strzela\u0107 sobie w stop\u0119, ale dalej nie zag\u0142\u0119biali\u015bmy si\u0119 w og\u00f3lne porady, takie jak \u201enie u\u017cywaj wzorca <noindex><a rel=\"nofollow\" href=\"https:\/\/en.wikipedia.org\/wiki\/Entity%E2%80%93attribute%E2%80%93value_model\">Entity Attribute Values<\/a><\/noindex> nie si\u0119gali\u015bmy. Projektowali\u015bmy zgodnie z zasadami normalizacji, unikaj\u0105c nadmiarowo\u015bci danych i nie martwili\u015bmy si\u0119 o przyspieszenie poszczeg\u00f3lnych zapyta\u0144. Gdy tylko przyszli pierwsi u\u017cytkownicy, napotkali\u015bmy problemy z wydajno\u015bci\u0105. Jak to zazwyczaj bywa, byli\u015bmy ca\u0142kowicie nie gotowi na to. Pierwsze problemy okaza\u0142y si\u0119 proste. Zazwyczaj wystarcza\u0142o dodanie nowego indeksu. Jednak nadszed\u0142 moment, kiedy proste \u0142atki przesta\u0142y dzia\u0142a\u0107. Zda\u0142em sobie spraw\u0119, \u017ce brakuje nam do\u015bwiadczenia i coraz trudniej jest nam zrozumie\u0107, co jest przyczyn\u0105 problem\u00f3w, wi\u0119c zatrudnili\u015bmy specjalist\u00f3w, kt\u00f3rzy pomogli nam w\u0142a\u015bciwie skonfigurowa\u0107 serwer, pod\u0142\u0105czy\u0107 monitoring, pokazali, gdzie patrze\u0107, aby uzyska\u0107 <noindex><a rel=\"nofollow\" href=\"https:\/\/www.postgresql.org\/docs\/9.6\/pgstatstatements.html\">statystyk\u0119<\/a><\/noindex>.<\/p>\n<h3>Obraz drugi. Statystyczny<\/h3>\n<p>\nMamy oko\u0142o 10 tysi\u0119cy r\u00f3\u017cnych zapyta\u0144, kt\u00f3re s\u0105 wykonywane na naszej bazie danych dziennie. Z tych 10 tysi\u0119cy s\u0105 potwory, kt\u00f3re s\u0105 wykonywane od 2 do 3 milion\u00f3w razy, z \u015brednim czasem wykonania wynosz\u0105cym 0.1-0.3 ms, oraz zapytania z \u015brednim czasem wykonania 30 sekund, kt\u00f3re s\u0105 wywo\u0142ywane 100 razy dziennie.<\/p>\n<p>Optymalizacja wszystkich 10 tysi\u0119cy zapyta\u0144 nie by\u0142a mo\u017cliwa, dlatego postanowili\u015bmy ustali\u0107, na jakie obszary skierowa\u0107 nasze wysi\u0142ki, aby poprawi\u0107 wydajno\u015b\u0107 bazy danych w odpowiedni spos\u00f3b. Po kilku iteracjach zacz\u0119li\u015bmy dzieli\u0107 zapytania na typy.<\/p>\n<h4>TOP zapytania<\/h4>\n<p>\nTo s\u0105 najci\u0119\u017csze zapytania, kt\u00f3re wymagaj\u0105 najwi\u0119cej czasu (czas ca\u0142kowity). S\u0105 to zapytania, kt\u00f3re s\u0105 wywo\u0142ywane bardzo cz\u0119sto lub kt\u00f3re maj\u0105 bardzo d\u0142ugi czas wykonania (d\u0142ugie i cz\u0119ste zapytania by\u0142y optymalizowane ju\u017c w pierwszych iteracjach walki o szybko\u015b\u0107). Ostatecznie serwer sp\u0119dza najwi\u0119cej czasu na ich wykonaniu. Warto oddzieli\u0107 top zapytania wed\u0142ug ca\u0142kowitego czasu wykonywania i osobno wed\u0142ug czasu IO. Sposoby optymalizacji takich zapyta\u0144 s\u0105 nieco r\u00f3\u017cne.<\/p>\n<p>Zwyczajow\u0105 praktyk\u0105 wszystkich firm jest praca z TOP zapytaniami. Jest ich niewiele, a optymalizacja nawet jednego zapytania mo\u017ce uwolni\u0107 5-10% zasob\u00f3w. Jednak w miar\u0119 \u201edojrzewania\u201d projektu optymalizacja TOP zapyta\u0144 staje si\u0119 coraz bardziej z\u0142o\u017conym zadaniem. Wszystkie proste rozwi\u0105zania zosta\u0142y ju\u017c zastosowane, a najci\u0119\u017csze zapytanie zabiera \u201ezaledwie\u201d 3-5% zasob\u00f3w. Je\u015bli TOP zapytania zajmuj\u0105 \u0142\u0105cznie mniej ni\u017c 30-40% czasu, to najprawdopodobniej ju\u017c podj\u0119li\u015bcie wysi\u0142ki, aby dzia\u0142a\u0142y szybko i nadszed\u0142 czas, aby przej\u015b\u0107 do optymalizacji zapyta\u0144 z nast\u0119pnej grupy.<br \/>\nPozostaje odpowiedzie\u0107 na pytanie, ile g\u00f3rnych zapyta\u0144 w\u0142\u0105czy\u0107 do tej grupy. Zwykle bior\u0119 nie mniej ni\u017c 10, ale nie wi\u0119cej ni\u017c 20. Staram si\u0119, aby czas pierwszego i ostatniego zapytania w grupie TOP r\u00f3\u017cni\u0142 si\u0119 nie wi\u0119cej ni\u017c dziesi\u0119ciokrotnie. To znaczy, je\u015bli czas wykonania zapyta\u0144 spada gwa\u0142townie z 1 miejsca do 10, bior\u0119 TOP-10, je\u015bli spadek jest bardziej stopniowy, zwi\u0119kszam rozmiar grupy do 15 lub 20.<br \/>\n<img decoding=\"async\" alt=\"Optymalizacja zapyta\u0144 bazy danych na przyk\u0142adzie us\u0142ugi B2B dla budowniczych\" src=\"\/wp-content\/uploads\/2019\/08\/2a9d9e6053d1aebb71aa213757bd2393.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<\/p>\n<h4>\u015aredniacy (medium)<\/h4>\n<p>\nTo s\u0105 wszystkie zapytania, kt\u00f3re s\u0105 bezpo\u015brednio za TOP, z wyj\u0105tkiem ostatnich 5-10%. Zazwyczaj w optymalizacji to w\u0142a\u015bnie te zapytania kryj\u0105 mo\u017cliwo\u015b\u0107 znacznego zwi\u0119kszenia wydajno\u015bci serwera. Mog\u0105 one \u201ezajmowa\u0107\u201d do 80%. Ale nawet je\u015bli ich udzia\u0142 przekroczy\u0142 50%, to znaczy, \u017ce czas na bardziej wnikliwe spojrzenie na nie.<\/p>\n<h4>Ogon (tail)<\/h4>\n<p>\nJak zosta\u0142o wspomniane, te zapytania pojawiaj\u0105 si\u0119 na ko\u0144cu i zajmuj\u0105 5-10% czasu. Mo\u017cna o nich zapomnie\u0107, tylko je\u015bli nie korzystasz z automatycznych narz\u0119dzi analizy zapyta\u0144, wtedy ich optymalizacja r\u00f3wnie\u017c mo\u017ce by\u0107 tania.<\/p>\n<p>Jak oceni\u0107 ka\u017cd\u0105 grup\u0119?<\/p>\n<p>U\u017cywam zapytania SQL, kt\u00f3re pomaga dokona\u0107 takiej oceny dla PostgreSQL (jestem pewien, \u017ce dla wielu innych system\u00f3w bazodanowych mo\u017cna napisa\u0107 podobne zapytanie)<\/p>\n<p><b class=\"spoiler_title\">Zapytanie SQL do oceny rozmiaru grup TOP-MEDIUM-TAIL<\/b><\/p>\n<pre><code class=\"sql\">SELECT sum(time_top) AS sum_top, sum(time_medium) AS sum_medium, sum(time_tail) FROM ( SELECT CASE WHEN rn  20 AND rn  800 THEN tt_percent ELSE 0 END AS time_tail FROM ( SELECT total_time \/ (SELECT sum(total_time) FROM pg_stat_statements) * 100 AS tt_percent, query, ROW_NUMBER () OVER (ORDER BY total_time DESC) AS rn FROM pg_stat_statements ORDER BY total_time DESC ) AS t ) AS ts\n<\/code><\/pre>\n<p>Wynik zapytania \u2013 trzy kolumny, z kt\u00f3rych ka\u017cda zawiera procent czasu po\u015bwi\u0119conego na przetwarzanie zapyta\u0144 z tej grupy. W obr\u0119bie zapytania znajduj\u0105 si\u0119 dwie liczby (w moim przypadku 20 i 800), kt\u00f3re oddzielaj\u0105 zapytania jednej grupy od drugiej.<\/p>\n<p>Oto jak mniej wi\u0119cej odnosz\u0105 si\u0119 udzia\u0142y zapyta\u0144 w momencie rozpocz\u0119cia prac nad optymalizacj\u0105 i teraz.<\/p>\n<p><img decoding=\"async\" alt=\"Optymalizacja zapyta\u0144 bazy danych na przyk\u0142adzie us\u0142ugi B2B dla budowniczych\" src=\"\/wp-content\/uploads\/2019\/08\/9c70ad9aba8b835c94729c9dda656eab.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nZ diagramu wida\u0107, \u017ce udzia\u0142 zapyta\u0144 TOP znacznie si\u0119 zmniejszy\u0142, za to wzros\u0142y zapytania \u201c\u015brednie\u201d.<br \/>\nPocz\u0105tkowo w zapytaniach TOP znajdowa\u0142y si\u0119 oczywiste b\u0142\u0119dy. Z czasem choroby wieku dzieci\u0119cego znikn\u0119\u0142y, udzia\u0142 zapyta\u0144 TOP si\u0119 zmniejszy\u0142, a my musieli\u015bmy w\u0142o\u017cy\u0107 coraz wi\u0119cej wysi\u0142ku, aby przyspieszy\u0107 ci\u0119\u017ckie zapytania. <\/p>\n<p><b class=\"spoiler_title\">Aby uzyska\u0107 tekst zapyta\u0144, u\u017cywamy takiego zapytania<\/b><\/p>\n<pre><code class=\"sql\">SELECT * FROM ( SELECT ROW_NUMBER () OVER (ORDER BY total_time DESC) AS rn, total_time \/ (SELECT sum(total_time) FROM pg_stat_statements) * 100 AS tt_percent, query FROM pg_stat_statements ORDER BY total_time DESC ) AS T WHERE rn  20 AND rn  800 -- TAIL\n<\/code><\/pre>\n<p>Oto lista najcz\u0119\u015bciej stosowanych technik, kt\u00f3re pomog\u0142y nam przyspieszy\u0107 zapytania TOP:<\/p>\n<ul>\n<li>Przeprojektowanie systemu, na przyk\u0142ad przekszta\u0142cenie logiki powiadomie\u0144 na message broker zamiast okresowych zapyta\u0144 do bazy danych<\/li>\n<li>Dodawanie lub zmiana indeks\u00f3w<\/li>\n<li>Przepisywanie zapyta\u0144 ORM na czysty SQL<\/li>\n<li>Przepisywanie logiki leniwego \u0142adowania danych<\/li>\n<li>Buforowanie poprzez denormalizacj\u0119 danych. Na przyk\u0142ad mamy po\u0142\u0105czenie tabeli Dostawa -&gt; Faktura -&gt; Zapytanie -&gt; Wniosek. To znaczy, \u017ce ka\u017cda dostawa jest powi\u0105zana z wnioskiem przez inne tabele. Aby nie powi\u0105zywa\u0107 wszystkich tabel w ka\u017cdym zapytaniu, skopiowali\u015bmy odniesienie do wniosku w tabeli Dostawa.<\/li>\n<li>Cache'owanie statycznych tabel z s\u0142ownikami oraz rzadko zmieniaj\u0105cych si\u0119 tabel w pami\u0119ci programu.<\/li>\n<\/ul>\n<p>\nCzasami zmiany prowadzi\u0142y do znacznych redesign\u00f3w, ale przynosi\u0142y 5-10% odci\u0105\u017cenia systemu i by\u0142y uzasadnione. Z czasem wydajno\u015b\u0107 mala\u0142a, a redesign stawa\u0142 si\u0119 coraz powa\u017cniejszy.<\/p>\n<p>Wtedy zwr\u00f3cili\u015bmy uwag\u0119 na drug\u0105 grup\u0119 zapyta\u0144 - grup\u0119 \u015bredniak\u00f3w. By\u0142o w niej znacznie wi\u0119cej zapyta\u0144 i wydawa\u0142o si\u0119, \u017ce analiza ca\u0142ej grupy zajmie du\u017co czasu. Jednak wi\u0119kszo\u015b\u0107 zapyta\u0144 okaza\u0142a si\u0119 bardzo prosta do optymalizacji, a wiele problem\u00f3w powtarza\u0142o si\u0119 dziesi\u0105tki razy w r\u00f3\u017cnych wariacjach. Oto przyk\u0142ady niekt\u00f3rych typowych optymalizacji, kt\u00f3re zastosowali\u015bmy do dziesi\u0105tek podobnych zapyta\u0144, a ka\u017cda grupa zoptymalizowanych zapyta\u0144 odci\u0105\u017ca\u0142a baz\u0119 danych o 3-5%.<\/p>\n<ul>\n<li> Zamiast sprawdzania obecno\u015bci rekord\u00f3w za pomoc\u0105 COUNT i pe\u0142nego skanowania tabeli, zacz\u0119to u\u017cywa\u0107 EXISTS.\n <\/li>\n<li>Pozbyli\u015bmy si\u0119 DISTINCT (nie ma og\u00f3lnego przepisu, ale czasami mo\u017cna si\u0119 go \u0142atwo pozby\u0107, przyspieszaj\u0105c zapytanie 10-100 razy).\n<p>Na przyk\u0142ad, zamiast zapytania do pobrania wszystkich kierowc\u00f3w z du\u017cej tabeli dostaw (DELIVERY) <\/p>\n<pre><code class=\"sql\">SELECT DISTINCT P.ID, P.FIRST_NAME, P.LAST_NAME\nFROM DELIVERY D JOIN PERSON P ON D.DRIVER_ID = P.ID\n<\/code><\/pre>\n<p>\nzrobili\u015bmy zapytanie na stosunkowo ma\u0142ej tabeli PERSON<\/p>\n<pre><code class=\"sql\">SELECT P.ID, P.FIRST_NAME, P.LAST_NAME\nFROM PERSON\nWHERE EXISTS(SELECT D.ID FROM DELIVERY WHERE D.DRIVER_ID = P.ID)\n<\/code><\/pre>\n<p>\nWydawa\u0142oby si\u0119, \u017ce u\u017cyli\u015bmy podzapytania skorelowanego, ale przynosi ono przyspieszenie powy\u017cej 10 razy.\n <\/li>\n<li>W wielu przypadkach ca\u0142kowicie zrezygnowali\u015bmy z COUNT i <br \/>\n<noindex><a rel=\"nofollow\" href=\"https:\/\/www.citusdata.com\/blog\/2016\/10\/12\/count-performance\/#dup_counts_estimated_filtered\">zast\u0105pili\u015bmy to obliczeniem przybli\u017conej warto\u015bci.<\/a><\/noindex>\n <\/li>\n<li>zamiast\n<pre><code class=\"sql\">UPPER(s) LIKE JOHN% \n<\/code><\/pre>\n<p>\nu\u017cywamy <\/p>\n<pre><code class=\"sql\">s ILIKE 'John%'\n<\/code><\/pre>\n<p>\n <\/li>\n<\/ul>\n<p>\nKa\u017cde konkretne zapytanie uda\u0142o si\u0119 przyspieszy\u0107 czasami o 3-1000 razy. Mimo imponuj\u0105cych wska\u017anik\u00f3w, na pocz\u0105tku uznawali\u015bmy, \u017ce nie ma sensu optymalizowa\u0107 zapytania, kt\u00f3re wykonuje si\u0119 w 10 ms, zajmuje trzecie setne miejsce w\u015br\u00f3d najci\u0119\u017cszych zapyta\u0144 i w og\u00f3lnym czasie obci\u0105\u017cenia bazy danych zajmuje u\u0142amki procenta. Jednak stosuj\u0105c t\u0119 sam\u0105 recept\u0119 do grupy jednolitarnych zapyta\u0144 uzyskiwali\u015bmy kilka procent oszcz\u0119dno\u015bci. Aby nie traci\u0107 czasu na r\u0119czne przegl\u0105danie wszystkich setek zapyta\u0144, napisali\u015bmy kilka prostych skrypt\u00f3w, kt\u00f3re z pomoc\u0105 wyra\u017ce\u0144 regularnych znajdowa\u0142y jednolite zapytania. W ko\u0144cu automatyczne wyszukiwanie grup zapyta\u0144 pozwoli\u0142o nam jeszcze bardziej poprawi\u0107 wydajno\u015b\u0107, po\u015bwi\u0119caj\u0105c skromne wysi\u0142ki.<\/p>\n<p>W rezultacie pracujemy ju\u017c od trzech lat na tym samym sprz\u0119cie. \u015arednie obci\u0105\u017cenie w ci\u0105gu dnia wynosi oko\u0142o 30%, a w szczytowych momentach si\u0119ga 70%. Liczba zapyta\u0144, jak i u\u017cytkownik\u00f3w wzros\u0142a prawie dziesi\u0119ciokrotnie. A wszystko to dzi\u0119ki sta\u0142emu monitorowaniu grup zapyta\u0144 TOP-MEDIUM. Gdy tylko pojawia si\u0119 nowe zapytanie w grupie TOP, natychmiast je analizujemy i pr\u00f3bujemy przyspieszy\u0107. Grup\u0119 MEDIUM przegl\u0105damy raz w tygodniu za pomoc\u0105 skrypt\u00f3w analizy zapyta\u0144. Je\u015bli znajdziemy nowe zapytania, kt\u00f3re ju\u017c wiemy jak zoptymalizowa\u0107, szybko je zmieniamy. Czasami odkrywamy nowe metody optymalizacji, kt\u00f3re mo\u017cna zastosowa\u0107 od razu do kilku zapyta\u0144. <\/p>\n<p>Z naszych prognoz wynika, \u017ce aktualny serwer wytrzyma wzrost liczby u\u017cytkownik\u00f3w jeszcze 3-5 razy. Prawda, \u017ce mamy jeden as w r\u0119kawie \u2014 nadal nie przekierowali\u015bmy zapyta\u0144 SELECT na lustrzane serwery, jak to si\u0119 zaleca. Ale nie robimy tego \u015bwiadomie, poniewa\u017c chcemy najpierw w pe\u0142ni wykorzysta\u0107 mo\u017cliwo\u015bci 'inteligentnej' optymalizacji przed w\u0142\u0105czeniem 'ci\u0119\u017ckiej artylerii'.<br \/>\nKrytyczne spojrzenie na wykonan\u0105 prac\u0119 mo\u017ce zasugerowa\u0107 zastosowanie pionowego skalowania. Zakupienie mocniejszego serwera, zamiast traci\u0107 czas specjalist\u00f3w. Serwer mo\u017ce kosztowa\u0107 niewiele, tym bardziej, \u017ce nasze limity pionowego skalowania s\u0105 jeszcze nieosi\u0105gni\u0119te. Jednak liczba zapyta\u0144 wzros\u0142a tylko dziesi\u0119ciokrotnie. W ci\u0105gu kilku lat zwi\u0119kszy\u0142 si\u0119 r\u00f3wnie\u017c funkcjonalno\u015b\u0107 systemu, a obecnie jest wi\u0119cej rodzaj\u00f3w zapyta\u0144. Funkcjonalno\u015b\u0107, kt\u00f3ra istnia\u0142a, dzi\u0119ki buforowaniu jest realizowana mniejsz\u0105 liczb\u0105 zapyta\u0144, a co wi\u0119cej, bardziej efektywnych zapyta\u0144. Oznacza to, \u017ce mo\u017cna \u015bmia\u0142o razy pi\u0119\u0107, aby uzyska\u0107 rzeczywisty wsp\u00f3\u0142czynnik przyspieszenia. Tak wi\u0119c, przy najbardziej skromnych obliczeniach, mo\u017cna powiedzie\u0107, \u017ce przyspieszenie wynios\u0142o 50 razy lub wi\u0119cej. Pionowe zeskalowanie serwera 50 razy by\u0142oby dro\u017csze. Szczeg\u00f3lnie bior\u0105c pod uwag\u0119, \u017ce raz przeprowadzona optymalizacja dzia\u0142a ca\u0142y czas, a rachunek za wynajmowany serwer przychodzi co miesi\u0105c.<br \/>\n<br \/>\u0179r\u00f3d\u0142o: <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/post\/461071\/\">habr.com<\/a><\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>\u041a\u0430\u043a \u0432\u044b\u0440\u0430\u0441\u0442\u0438 \u0432 10 \u0440\u0430\u0437 \u043f\u043e\u0434 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u0443 \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 \u043a \u0411\u0414 \u043d\u0435 \u043f\u0435\u0440\u0435\u0435\u0437\u0436\u0430\u044f \u043d\u0430 \u0431\u043e\u043b\u0435\u0435 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0439 \u0441\u0435\u0440\u0432\u0435\u0440 \u0438 \u0441\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0440\u0430\u0431\u043e\u0442\u043e\u0441\u043f\u043e\u0441\u043e\u0431\u043d\u043e\u0441\u0442\u044c \u0441\u0438\u0441\u0442\u0435\u043c\u044b? \u042f \u0440\u0430\u0441\u0441\u043a\u0430\u0436\u0443, \u043a\u0430\u043a \u043c\u044b \u0431\u043e\u0440\u043e\u043b\u0438\u0441\u044c \u0441 \u043f\u0430\u0434\u0435\u043d\u0438\u0435\u043c \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u043d\u0430\u0448\u0435\u0439 \u0431\u0430\u0437\u044b \u0434\u0430\u043d\u043d\u044b\u0445, \u043a\u0430\u043a \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043b\u0438 SQL \u0437\u0430\u043f\u0440\u043e\u0441\u044b, \u0447\u0442\u043e\u0431\u044b \u043e\u0431\u0441\u043b\u0443\u0436\u0438\u0432\u0430\u0442\u044c \u043a\u0430\u043a \u043c\u043e\u0436\u043d\u043e \u0431\u043e\u043b\u044c\u0448\u0435 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439 \u0438 \u043d\u0435 \u043f\u043e\u0432\u044b\u0448\u0430\u0442\u044c \u0440\u0430\u0441\u0445\u043e\u0434\u044b \u043d\u0430 \u0432\u044b\u0447\u0438\u0441\u043b\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u0440\u0435\u0441\u0443\u0440\u0441\u044b. \u042f \u0434\u0435\u043b\u0430\u044e \u0441\u0435\u0440\u0432\u0438\u0441 \u0434\u043b\u044f \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0431\u0438\u0437\u043d\u0435\u0441 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0430\u043c\u0438 [&hellip;]<\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"author":1,"featured_media":27493,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[688],"tags":[],"class_list":["post-36704","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-administrirovanie"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.1.1 - aioseo.com -->\n\t<meta name=\"description\" content=\"\u041a\u0430\u043a \u0432\u044b\u0440\u0430\u0441\u0442\u0438 \u0432 10 \u0440\u0430\u0437 \u043f\u043e\u0434 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u0443 \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 \u043a \u0411\u0414 \u043d\u0435 \u043f\u0435\u0440\u0435\u0435\u0437\u0436\u0430\u044f \u043d\u0430 \u0431\u043e\u043b\u0435\u0435 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0439 \u0441\u0435\u0440\u0432\u0435\u0440 \u0438 \u0441\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0440\u0430\u0431\u043e\u0442\u043e\u0441\u043f\u043e\u0441\u043e\u0431\u043d\u043e\u0441\u0442\u044c \u0441\u0438\u0441\u0442\u0435\u043c\u044b?\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"Yuri Gagarin\"\/>\n\t<link rel=\"canonical\" href=\"https:\/\/prohoster.info\/pl\/blog\/administrirovanie\/optimizatsiya-zaprosov-bazy-dannyh-na-primere-b2b-servisa-dlya-stroitelej\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.1.1\" \/>\n\t\t<meta property=\"og:locale\" content=\"pl_PL\" \/>\n\t\t<meta property=\"og:site_name\" content=\"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"\ud83e\udd47\u041e\u043f\u0442\u0438\u043c\u0438\u0437\u0430\u0446\u0438\u044f \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 \u0431\u0430\u0437\u044b \u0434\u0430\u043d\u043d\u044b\u0445 \u043d\u0430 \u043f\u0440\u0438\u043c\u0435\u0440\u0435 B2B \u0441\u0435\u0440\u0432\u0438\u0441\u0430 \u0434\u043b\u044f \u0441\u0442\u0440\u043e\u0438\u0442\u0435\u043b\u0435\u0439 | ProHoster\" \/>\n\t\t<meta property=\"og:description\" content=\"\u041a\u0430\u043a \u0432\u044b\u0440\u0430\u0441\u0442\u0438 \u0432 10 \u0440\u0430\u0437 \u043f\u043e\u0434 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u0443 \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 \u043a \u0411\u0414 \u043d\u0435 \u043f\u0435\u0440\u0435\u0435\u0437\u0436\u0430\u044f \u043d\u0430 \u0431\u043e\u043b\u0435\u0435 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0439 \u0441\u0435\u0440\u0432\u0435\u0440 \u0438 \u0441\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0440\u0430\u0431\u043e\u0442\u043e\u0441\u043f\u043e\u0441\u043e\u0431\u043d\u043e\u0441\u0442\u044c \u0441\u0438\u0441\u0442\u0435\u043c\u044b?\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/pl\/blog\/administrirovanie\/optimizatsiya-zaprosov-bazy-dannyh-na-primere-b2b-servisa-dlya-stroitelej\" \/>\n\t\t<meta property=\"og:image\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:secure_url\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:width\" content=\"350\" \/>\n\t\t<meta property=\"og:image:height\" content=\"350\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2019-10-31T19:13:15+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2019-10-31T19:13:15+00:00\" \/>\n\t\t<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<meta property=\"article:author\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"\ud83e\udd47Optymalizacja zapyta\u0144 bazy danych na przyk\u0142adzie us\u0142ugi B2B dla budowniczych | ProHoster","description":"Jak zwi\u0119kszy\u0107 liczb\u0119 zapyta\u0144 do bazy danych dziesi\u0119ciokrotnie, nie przeprowadzaj\u0105c migracji na bardziej wydajny serwer i zachowuj\u0105c funcionalno\u015b\u0107 systemu?","canonical_url":"https:\/\/prohoster.info\/pl\/blog\/administrirovanie\/optimizatsiya-zaprosov-bazy-dannyh-na-primere-b2b-servisa-dlya-stroitelej","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"pl_PL","og:site_name":"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b","og:type":"article","og:title":"\ud83e\udd47\u041e\u043f\u0442\u0438\u043c\u0438\u0437\u0430\u0446\u0438\u044f \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 \u0431\u0430\u0437\u044b \u0434\u0430\u043d\u043d\u044b\u0445 \u043d\u0430 \u043f\u0440\u0438\u043c\u0435\u0440\u0435 B2B \u0441\u0435\u0440\u0432\u0438\u0441\u0430 \u0434\u043b\u044f \u0441\u0442\u0440\u043e\u0438\u0442\u0435\u043b\u0435\u0439 | ProHoster","og:description":"\u041a\u0430\u043a \u0432\u044b\u0440\u0430\u0441\u0442\u0438 \u0432 10 \u0440\u0430\u0437 \u043f\u043e\u0434 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u0443 \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 \u043a \u0411\u0414 \u043d\u0435 \u043f\u0435\u0440\u0435\u0435\u0437\u0436\u0430\u044f \u043d\u0430 \u0431\u043e\u043b\u0435\u0435 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0439 \u0441\u0435\u0440\u0432\u0435\u0440 \u0438 \u0441\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0440\u0430\u0431\u043e\u0442\u043e\u0441\u043f\u043e\u0441\u043e\u0431\u043d\u043e\u0441\u0442\u044c \u0441\u0438\u0441\u0442\u0435\u043c\u044b?","og:url":"https:\/\/prohoster.info\/pl\/blog\/administrirovanie\/optimizatsiya-zaprosov-bazy-dannyh-na-primere-b2b-servisa-dlya-stroitelej","og:image":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:secure_url":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:width":350,"og:image:height":350,"article:published_time":"2019-10-31T19:13:15+00:00","article:modified_time":"2019-10-31T19:13:15+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"36704","title":null,"description":null,"keywords":null,"keyphrases":null,"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":null,"og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"","isEnabled":true},"graphs":[]},"schema_type":null,"schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":null,"robots_max_videopreview":null,"robots_max_imagepreview":"large","priority":null,"frequency":null,"local_seo":null,"seo_analyzer_scan_date":"2026-01-22 04:30:19","breadcrumb_settings":null,"limit_modified_date":false,"reviewed_by":null,"ai":null,"created":"2021-03-01 01:40:22","updated":"2026-01-22 04:30:19","focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"gt_translate_keys":[{"key":"link","format":"url"}],"_links":{"self":[{"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/posts\/36704","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/comments?post=36704"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/posts\/36704\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/media\/27493"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/media?parent=36704"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/categories?post=36704"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/tags?post=36704"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}