{"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\/hr\/blog\/administrirovanie\/optimizatsiya-zaprosov-bazy-dannyh-na-primere-b2b-servisa-dlya-stroitelej","title":{"rendered":"Optimizacija upita baza podataka na primjeru B2B usluge za gra\u0111evinare","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p>Kako pove\u0107ati broj upita na bazi podataka deset puta bez preseljenja na ja\u010di server i zadr\u017eati funkcionalnost sistema? Objasni\u0107u kako smo se borili protiv opadanja performansi na\u0161e baze podataka, kako smo optimizovali SQL upite da slu\u017ee \u0161to ve\u0107em broju korisnika, a da ne pove\u0107amo tro\u0161kove ra\u010dunarskih resursa.<br \/>\n<noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><br \/>\nRazvijam servis za upravljanje poslovnim procesima u gra\u0111evinskim kompanijama. Sa nama radi oko 3.000 kompanija. Vi\u0161e od 10.000 ljudi svakodnevno koristi na\u0161 sistem od 4 do 10 sati. Re\u0161ava razne zadatke planiranja, obave\u0161tavanja, upozoravanja, validacije\u2026 Koristimo PostgreSQL 9.6. U bazi podataka imamo oko 300 tabela i svakodnevno se izvr\u0161i do 200 miliona upita (10.000 razli\u010ditih). U proseku imamo 3.000 do 4.000 upita u sekundi, a u najsna\u017enijim trenucima vi\u0161e od 10.000 upita po sekundi. Veliki deo upita su OLAP. Dodavanja, modifikacije i brisanja su znatno manja, \u0161to zna\u010di da je OLTP optere\u0107enje relativno malo. Sve ove brojke sam naveo kako biste mogli proceniti razmeru na\u0161eg projekta i razumeti koliko na\u0161u iskustvo mo\u017ee biti korisno za vas.<\/p>\n<h3>Prva slika. Lirska<\/h3>\n<p>\nKada smo zapo\u010deli razvoj, nismo mnogo razmi\u0161ljali o tome kakvo optere\u0107enje \u0107e biti na bazi podataka i \u0161ta \u0107emo raditi ukoliko server prestane da izdr\u017ei. Tokom projektovanja baze podataka pratili smo op\u0161te preporuke i trudili se da ne napravimo gre\u0161ke, ali nismo i\u0161li dalje od op\u0107ih saveta poput \"ne koristite obrazac <noindex><a rel=\"nofollow\" href=\"https:\/\/en.wikipedia.org\/wiki\/Entity%E2%80%93attribute%E2%80%93value_model\">Entity Attribute Values<\/a><\/noindex> nismo i\u0161li. Projektovali smo prema principima normalizacije izbegavaju\u0107i suvi\u0161nost podataka i nismo se brinuli o ubrzanju odre\u0111enih upita. Kada su prvi korisnici do\u0161li, suo\u010dili smo se s problemom performansi. Kao i obi\u010dno, nismo bili apsolutno spremni za to. Prvi problemi su bili jednostavni. Uglavnom se sve re\u0161avalo dodavanjem novog indeksa. Me\u0111utim, do\u0161ao je trenutak kada su jednostavne nadogradnje prestale da funkcioni\u0161u. Svjesni da nam nedostaje iskustva i da nam je sve te\u017ee razumeti uzrok problema, anga\u017eovali smo stru\u010dnjake koji su nam pomogli da pravilno konfiguri\u0161emo server, pove\u017eemo monitoring i pokazali nam gde da gledamo za dobijanje <noindex><a rel=\"nofollow\" href=\"https:\/\/www.postgresql.org\/docs\/9.6\/pgstatstatements.html\">statistike<\/a><\/noindex>.<\/p>\n<h3>Druga slika. Statisti\u010dka<\/h3>\n<p>\nDakle, imamo oko 10 tisu\u0107a razli\u010ditih zahtjeva koji se izvr\u0161avaju na na\u0161oj bazi podataka svakodnevno. Od tih 10 tisu\u0107a, postoje 'monstri' koji se izvr\u0161avaju 2-3 milijuna puta s prosje\u010dnim vremenom izvr\u0161enja od 0.1-0.3 ms, te zahtjevi koji imaju prosje\u010dno vreme izvr\u0161enja od 30 sekundi, a pozivaju se 100 puta dnevno.<\/p>\n<p>Optimizirati svih 10 tisu\u0107a zahtjeva nije bilo mogu\u0107e, pa smo odlu\u010dili istra\u017eiti kuda usmjeriti napore kako bismo pravilno pove\u0107ali performanse baze podataka. Nakon nekoliko iteracija, po\u010deli smo dijeliti zahtjeve prema vrstama.<\/p>\n<h4>TOP zahtjevi<\/h4>\n<p>\nTo su najte\u017ei zahtjevi koji zauzimaju najvi\u0161e vremena (ukupno vrijeme). To su zahtjevi koji se ili vrlo \u010desto pozivaju ili zahtjevi koji se upravo vrlo dugo izvr\u0161avaju (dugi i \u010desti zahtjevi su optimizirani jo\u0161 u prvim iteracijama borbe za brzinu). Na kraju, server tro\u0161i najvi\u0161e vremena na njihovo izvr\u0161avanje. Va\u017eno je odvojiti top zahtjeve prema ukupnom vremenu izvr\u0161enja i zasebno prema IO vremenu. Na\u010dini optimizacije takvih zahtjeva su malo druga\u010diji.<\/p>\n<p>Uobi\u010dajena praksa svih kompanija je rad s TOP zahtjevima. Ima ih malo i optimizacija \u010dak i jednog zahtjeva mo\u017ee osloboditi 5-10% resursa. Me\u0111utim, kako projekt 'odrasta', optimizacija TOP zahtjeva postaje sve slo\u017eeniji zadatak. Svi jednostavni na\u010dini su ve\u0107 isprobani, a najte\u017ei zahtjev tro\u0161i 'samo' 3-5% resursa. Ako TOP zahtjevi ukupno zauzimaju manje od 30-40% vremena, vjerojatno ste ve\u0107 ulo\u017eili napore kako bi radili brzo i do\u0161lo je vrijeme za prelazak na optimizaciju zahtjeva iz sljede\u0107e grupe.<br \/>\nPreostaje odgovoriti na pitanje koliko gornjih zahtjeva uklju\u010diti u ovu grupu. Obi\u010dno uzimam ne manje od 10, ali ne vi\u0161e od 20. Poku\u0161avam osigurati da se vrijeme prvog i posljednjeg u TOP grupi razlikuje ne vi\u0161e od 10 puta. To jest, ako se vrijeme izvr\u0161enja zahtjeva naglo smanjuje sa 1. mjesta na 10., uzimam TOP-10, ako je pad postupan, pove\u0107avam veli\u010dinu grupe na 15 ili 20.<br \/>\n<img decoding=\"async\" alt=\"Optimizacija upita baza podataka na primjeru B2B usluge za gra\u0111evinare\" src=\"\/wp-content\/uploads\/2019\/08\/2a9d9e6053d1aebb71aa213757bd2393.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<\/p>\n<h4>Srednjaci (medium)<\/h4>\n<p>\nTo su svi zahtjevi koji dolaze odmah nakon TOP-a, osim posljednjih 5-10%. Obi\u010dno u optimizaciji upravo tih zahtjeva le\u017ei mogu\u0107nost zna\u010dajnog pove\u0107anja performansi servera. Ovi zahtjevi mogu 'zauzimati' do 80%. Ali \u010dak i ako njihov udio prema\u0161i 50%, tada je pravo vrijeme da im se posveti pa\u017enja.<\/p>\n<h4>Rep (tail)<\/h4>\n<p>\nKao \u0161to je re\u010deno, ovi upiti dolaze na kraju i oduzimaju 5-10% vremena. Mo\u017eete ih zaboraviti samo ako ne koristite automatske alate za analizu upita, tada njihova optimizacija tako\u0111e mo\u017ee biti povoljnija.<\/p>\n<p>Kako procijeniti svaku grupu?<\/p>\n<p>Koristim SQL upit koji poma\u017ee u toj procjeni za PostgreSQL (siguran sam da se mo\u017ee napisati sli\u010dan upit za mnoge druge DBMS).<\/p>\n<p><b class=\"spoiler_title\">SQL upit za procjenu veli\u010dine TOP-MEDIUM-TAIL grupa.<\/b><\/p>\n<pre><code class=\"sql\">SELECT sum(time_top) AS sum_top, sum(time_medium) AS sum_medium, sum(time_tail) AS sum_tail\nFROM\n(\n  SELECT CASE WHEN rn  20 AND rn  800              THEN tt_percent ELSE 0 END AS time_tail\n  FROM (\n    SELECT total_time \/ (SELECT sum(total_time) FROM pg_stat_statements) * 100 AS tt_percent, query,\n    ROW_NUMBER () OVER (ORDER BY total_time DESC) AS rn\n    FROM pg_stat_statements\n    ORDER BY total_time DESC\n  ) AS t\n)\nAS ts\n<\/code><\/pre>\n<p>Rezultat upita - tri kolone, svaka od njih sadr\u017ei postotak vremena koje se tro\u0161i na obradu upita iz te grupe. Unutra upita postoje dva broja (u mom slu\u010daju to su 20 i 800), koji odvajaju upite jedne grupe od druge.<\/p>\n<p>Ovako otprilike izgleda odnos izme\u0111u postotaka upita u trenutku po\u010detka optimizacije i sada.<\/p>\n<p><img decoding=\"async\" alt=\"Optimizacija upita baza podataka na primjeru B2B usluge za gra\u0111evinare\" src=\"\/wp-content\/uploads\/2019\/08\/9c70ad9aba8b835c94729c9dda656eab.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nIz dijagrama se vidi da je udio TOP upita naglo smanjen, a udio \"srednjaka\" se pove\u0107ao.<br \/>\nIsprva su u TOP upite ulazili o\u010digledni propusti. S vremenom su dje\u010dje bolesti nestale, udio TOP upita se smanjivao, a bilo je potrebno ulo\u017eiti sve vi\u0161e truda da se ubrzaju te\u0161ki upiti. <\/p>\n<p><b class=\"spoiler_title\">Da bismo dobili tekst upita, koristimo ovakav upit.<\/b><\/p>\n<pre><code class=\"sql\">SELECT * FROM (\n  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\n  FROM pg_stat_statements\n  ORDER BY total_time DESC\n) AS T\nWHERE\nrn  20 AND rn  800  -- TAIL\n<\/code><\/pre>\n<p>Evo popisa naj\u010de\u0161\u0107e kori\u0161tenih tehnika koje su nam pomagale da ubrzamo TOP upite:<\/p>\n<ul>\n<li>Redizajn sistema, na primjer, prerada logike obavijesti pomo\u0107u message brokera umjesto periodi\u010dnih upita ka bazi podataka.<\/li>\n<li>Dodavanje ili promjena indeksa.<\/li>\n<li>Prepisivanje ORM upita u \u010disti SQL.<\/li>\n<li>Prepisivanje logike lazy u\u010ditavanja podataka.<\/li>\n<li>Ke\u0161iranje kroz denormalizaciju podataka. Na primjer, imamo vezu izme\u0111u tabela Dostava -&gt; Ra\u010dun -&gt; Upit -&gt; Zahtjev. Svaka dostava je povezana s zahtjevom kroz druge tabele. Da ne bismo povezivali sve tabele u svakom upitu, duplicirali smo vezu na zahtjev u tabeli Dostava.<\/li>\n<li>Ke\u0161iranje stati\u010dkih tablica sa referencama i rijetko promjenjivih tablica u memoriji programa.<\/li>\n<\/ul>\n<p>\nPonekad su promjene zahtijevale zna\u010dajan redizajn, ali su pru\u017eale 5-10% olak\u0161anja sustava i bile su opravdane. Vremenom je u\u010dinkovitost postajala sve manja, a redizajn je postajao sve ozbiljniji.<\/p>\n<p>Tada smo obratili pa\u017enju na drugu grupu zahtjeva \u2013 grupu srednjaka. U njoj je bilo znatno vi\u0161e zahtjeva, a \u010dinilo se da \u0107e analiza cijele grupe oduzeti jako puno vremena. Me\u0111utim, ve\u0107ina zahtjeva bila je vrlo jednostavna za optimizaciju, a mnogi problemi ponavljali su se deset puta u raznim varijacijama. Ovo su primjeri nekih tipi\u010dnih optimizacija koje smo primijenili na desetinama sli\u010dnih zahtjeva, a svaka grupa optimiziranih zahtjeva smanjila je optere\u0107enje Baze podataka za 3-5%.<\/p>\n<ul>\n<li> Umjesto provjere postojanja zapisa pomo\u0107u COUNT-a i cjelovitog skeniranja tablice po\u010deli smo koristiti EXISTS.\n <\/li>\n<li>Oslobodili smo se DISTINCT-a (nema op\u0107eg recepta, ali ga nekad lako mo\u017eemo eliminirati i ubrzati upit 10-100 puta).\n<p>Na primjer, umjesto upita za odabir svih voza\u010da iz velike tablice dostava (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>\nnapravili smo upit iz relativno male tablice 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>\nNaizgled, koristili smo koreliranu podupit, ali ona donosi ubrzanje vi\u0161e od 10 puta.\n <\/li>\n<li>U mnogim slu\u010dajevima smo uop\u0107e odustali od COUNT-a i <br \/>\n<noindex><a rel=\"nofollow\" href=\"https:\/\/www.citusdata.com\/blog\/2016\/10\/12\/count-performance\/#dup_counts_estimated_filtered\">zamijenili ga s prora\u010dunom pribli\u017ene vrijednosti.<\/a><\/noindex>\n <\/li>\n<li>umjesto\n<pre><code class=\"sql\">UPPER(s) LIKE JOHN% \n<\/code><\/pre>\n<p>\nkoristimo <\/p>\n<pre><code class=\"sql\">s ILIKE \u201cJohn%\u201d\n<\/code><\/pre>\n<p>\n <\/li>\n<\/ul>\n<p>\nSvaki konkretan upit uspijevali smo ubrzati ponekad 3-1000 puta. Usprkos impresioniraju\u0107im pokazateljima, na po\u010detku se \u010dinilo da nema smisla optimizirati upit koji se izvr\u0161ava 10 ms, ulazi u 300. po redu najte\u017eih upita i u ukupnom vremenu optere\u0107enja na Bazi podataka zauzima stotinke postotka. No primjenom istog recepta na grupu sli\u010dnih upita, uspjeli smo povratiti nekoliko postotaka. Kako bismo u\u0161tedjeli vrijeme na ru\u010dnom pregledu svih stotina upita, napisali smo nekoliko jednostavnih skripti koje su uz pomo\u0107 regularnih izraza nalazile sli\u010dne upite. Na kraju, automatsko pretra\u017eivanje grupa upita omogu\u0107ilo nam je dodatno pobolj\u0161anje na\u0161e u\u010dinkovitosti uz minimalne napore.<\/p>\n<p>Na kraju, radimo ve\u0107 tri godine na istom hardveru. Prosje\u010dno optere\u0107enje je oko 30%, a u \u0161picama dose\u017ee do 70%. Broj zahtjeva i korisnika pove\u0107ao se otprilike 10 puta. A sve to zahvaljuju\u0107i stalnom monitoringu tih grupa zahtjeva TOP-MEDIUM. \u010cim se pojavi novi zahtjev u grupi TOP, odmah ga analiziramo i poku\u0161avamo ubrzati. Grupu MEDIUM pregledavamo jednom tjedno pomo\u0107u skripti za analizu zahtjeva. Ako prona\u0111emo nove zahtjeve za koje znamo kako optimizirati, brzo ih mijenjamo. Ponekad pronalazimo nove metode optimizacije koje mo\u017eemo odmah primijeniti na nekoliko zahtjeva. <\/p>\n<p>Prema na\u0161im prognozama, trenutni server \u0107e izdr\u017eati pove\u0107anje broja korisnika jo\u0161 3-5 puta. Ipak, imamo jo\u0161 jedan adut u rukavu - jo\u0161 uvijek nismo prebacili SELECT zahtjeve na mirror, kao \u0161to se preporu\u010duje. No, to \u010dinimo svjesno jer \u017eelimo prvo iscrpiti mogu\u0107nosti 'pametne' optimizacije prije nego \u0161to anga\u017eiramo 'te\u0161ku artiljeriju'.<br \/>\nKriti\u010dki pogled na ura\u0111eni posao mo\u017ee sugerirati kori\u0161tenje vertikalnog skaliranja. Kupiti mo\u0107niji server umjesto gubljenja vremena stru\u010dnjaka. Server ne bi trebao ko\u0161tati puno, pogotovo jer na\u0161i limiti vertikalnog skaliranja jo\u0161 nisu iscrpljeni. Me\u0111utim, broj zahtjeva je porastao samo 10 puta. Tijekom nekoliko godina, funkcionalnost sustava se pove\u0107ala i sada imamo vi\u0161e vrsta zahtjeva. Ona funkcionalnost koja je bila, zahvaljuju\u0107i ke\u0161iranju, sada se izvr\u0161ava s manjim brojem zahtjeva, a oni su u\u010dinkovitiji. To zna\u010di da mo\u017eemo sigurno pomno\u017eiti jo\u0161 s 5 kako bismo dobili stvarni koeficijent ubrzanja. Dakle, prema najskromnijim prora\u010dunima, mo\u017eemo re\u0107i da je ubrzanje bilo 50 i vi\u0161e puta. Vertikalno pove\u0107anje servera 50 puta bi bilo skuplje. Pogotovo uzimaju\u0107i u obzir da jednom izvr\u0161ena optimizacija radi cijelo vrijeme, a ra\u010dun za iznajmljeni server dolazi svaki mjesec.<br \/>\n<br \/>Izvor: <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.4 - 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\/hr\/blog\/administrirovanie\/optimizatsiya-zaprosov-bazy-dannyh-na-primere-b2b-servisa-dlya-stroitelej\" \/>\n\t\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.4\" \/>\n\t\t<meta property=\"og:locale\" content=\"hr_HR\" \/>\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\/hr\/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\udd47Optimizacija zahtjeva baze podataka na primjeru B2B usluge za graditelje | ProHoster","description":"Kako rasti 10 puta u broju zahtjeva prema Bazi podataka bez selidbe na ja\u010di server i o\u010duvati funkcionalnost sustava?","canonical_url":"https:\/\/prohoster.info\/hr\/blog\/administrirovanie\/optimizatsiya-zaprosov-bazy-dannyh-na-primere-b2b-servisa-dlya-stroitelej","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"hr_HR","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\/hr\/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\/hr\/wp-json\/wp\/v2\/posts\/36704","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/hr\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/hr\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/hr\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/hr\/wp-json\/wp\/v2\/comments?post=36704"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/hr\/wp-json\/wp\/v2\/posts\/36704\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/hr\/wp-json\/wp\/v2\/media\/27493"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/hr\/wp-json\/wp\/v2\/media?parent=36704"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/hr\/wp-json\/wp\/v2\/categories?post=36704"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/hr\/wp-json\/wp\/v2\/tags?post=36704"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}