{"id":75530,"date":"2020-03-26T19:42:23","date_gmt":"2020-03-26T17:42:23","guid":{"rendered":"https:\/\/prohoster.info\/blog\/administrirovanie\/vyvod-rezultatov-poiska-i-problemy-s-proizvoditelnostyu"},"modified":"2020-03-26T19:42:23","modified_gmt":"2020-03-26T17:42:23","slug":"vyvod-rezultatov-poiska-i-problemy-s-proizvoditelnostyu","status":"publish","type":"post","link":"https:\/\/prohoster.info\/et\/blog\/administrirovanie\/vyvod-rezultatov-poiska-i-problemy-s-proizvoditelnostyu","title":{"rendered":"Otsingutulemuste kuvamine ja j\u00f5udlusprobleemid.","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p>\u00dcks t\u00fc\u00fcpiline stsenaarium k\u00f5igis tuttavates rakendustes on andmete otsimine teatud kriteeriumide alusel ja nende esitamine mugaval lugemisviisil. Siin v\u00f5ivad olla ka lisav\u00f5imalused sorteerimiseks, r\u00fchmitamiseks ja lehemittev\u00e4ljundiks. \u00dclesanne on iseenesest triviaalne, kuid selle lahendamisel teevad paljud arendajad mitmeid vigu, mis halvavad seej\u00e4rel j\u00f5udlust. Proovime vaadata erinevaid lahendusi sellele \u00fclesandele ja formuleerime soovitusi, et valida k\u00f5ige t\u00f5husam teostus.<\/p>\n<p><img decoding=\"async\" alt=\"Otsingutulemuste kuvamine ja j\u00f5udlusprobleemid.\" src=\"\/wp-content\/uploads\/2020\/03\/364ab29c4a6117ff441b933a38ec8401.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<h2>Lehemittev\u00e4lja variant #1<\/h2>\n<p>\nK\u00f5ige lihtsam variant, mis p\u00e4he tuleb, on otsingutulemuste lehemittev\u00e4lja esitamine k\u00f5ige klassikalisemas vormis.<\/p>\n<p><img decoding=\"async\" alt=\"Otsingutulemuste kuvamine ja j\u00f5udlusprobleemid.\" src=\"\/wp-content\/uploads\/2020\/03\/4957d9ad21a8a0c70390b224fe76cb33.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\nOletame, et rakenduses kasutatakse relatsioonilist andmebaasi. Sel juhul tuleb selle kujul teabe kuvamiseks t\u00e4ita kaks SQL p\u00e4ringut:<\/p>\n<ul>\n<li>Saada praeguse lehe jaoks read.<\/li>\n<li>Loendada otsingu kriteeriumidele vastavad read \u2013 see on vajalik lehtede n\u00e4itamiseks.<\/li>\n<\/ul>\n<p>\nVaatame esimest p\u00e4ringut n\u00e4ite p\u00f5hjal testimis MS SQL andmebaasist <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/Microsoft\/sql-server-samples\/releases\/download\/adventureworks\/AdventureWorks2016_EXT.bak\">AdventureWorks <\/a><\/noindex>2016 serveri jaoks. Selleks kasutame tabelit Sales.SalesOrderHeader:<\/p>\n<pre><code class=\"sql\">SELECT * FROM Sales.SalesOrderHeader\nORDER BY OrderDate DESC\nOFFSET 0 ROWS\nFETCH NEXT 50 ROWS ONLY\n<\/code><\/pre>\n<p>\n\u00dclaltoodud p\u00e4ring kuvab esimesed 50 tellimust nimekirjast, mis on sorteeritud lisamise kuup\u00e4eva j\u00e4rgi kahanevas j\u00e4rjekorras, teisis\u00f5nu \u2013 50 viimast tellimust.<\/p>\n<p>See t\u00e4idetakse kiiresti testimisandmebaasis, aga vaatame t\u00e4itmisplaani ja sisendi-v\u00e4ljundi statistikat:<\/p>\n<p><img decoding=\"async\" alt=\"Otsingutulemuste kuvamine ja j\u00f5udlusprobleemid.\" src=\"\/wp-content\/uploads\/2020\/03\/248e4b64593c7000216b46777183d639.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<pre><code class=\"plaintext\">Tabel 'SalesOrderHeader'. Skaneerimise arv 1, loogilised lugemised 698, f\u00fc\u00fcsilised lugemised 0, eelnevad lugemised 0, lob loogilised lugemised 0, lob f\u00fc\u00fcsilised lugemised 0, lob eelnevad lugemised 0.<\/code><\/pre>\n<p>\n<i>Iga p\u00e4ringu sisendi\/v\u00e4ljundi statistika saamiseks saab p\u00e4ringute t\u00e4itmise keskkonnas k\u00e4ivitada k\u00e4su SET STATISTICS IO ON.<\/i><\/p>\n<p>Nagu t\u00e4itmisplaanist n\u00e4ha, on k\u00f5ige ressursimahukam k\u00f5igi ridade sorteerimine algsest tabelist lisamise kuup\u00e4eva j\u00e4rgi. Probleem on see, et mida rohkem ridu tabelisse lisandub, seda 'raske'maks muutub sorteerimine. Selliste olukordade v\u00e4ltimiseks tuleks praktikas indeks lisada lisamise kuup\u00e4eva j\u00e4rgi ja vaadata, kas ressursikasutus on muutunud:<\/p>\n<p><img decoding=\"async\" alt=\"Otsingutulemuste kuvamine ja j\u00f5udlusprobleemid.\" src=\"\/wp-content\/uploads\/2020\/03\/a33e1eadf6f8f8b516b9bb834ad7ad86.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<pre><code class=\"plaintext\">Tabel 'SalesOrderHeader'. Skaneerimise arv 1, loogilised lugemised 165, f\u00fc\u00fcsilised lugemised 0, eelnevad lugemised 5, lob loogilised lugemised 0, lob f\u00fc\u00fcsilised lugemised 0, lob eelnevad lugemised 0.\n<\/code><\/pre>\n<p>\nIlmselgelt on olukord muutunud palju paremaks. Aga kas k\u00f5ik probleemid on lahendatud? Muudame p\u00e4ringut, et otsida tellimusi, mille kaupade koguv\u00e4\u00e4rtus \u00fcletab 100 dollarit:<\/p>\n<pre><code class=\"sql\">SELECT * FROM Sales.SalesOrderHeader\nWHERE SubTotal &gt; 100\nORDER BY OrderDate DESC\nOFFSET 0 ROWS\nFETCH NEXT 50 ROWS ONLY\n<\/code><\/pre>\n<p>\n<img decoding=\"async\" alt=\"Otsingutulemuste kuvamine ja j\u00f5udlusprobleemid.\" src=\"\/wp-content\/uploads\/2020\/03\/e057bfc89e11a31c6d2855b93ec3c747.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<pre><code class=\"plaintext\">Tabel 'SalesOrderHeader'. Skaneerimise arv 1, loogilised lugemised 1081, f\u00fc\u00fcsilised lugemised 0, eelnevad lugemised 0, lob loogilised lugemised 0, lob f\u00fc\u00fcsilised lugemised 0, lob eelnevad lugemised 0.<\/code><\/pre>\n<p>\nMeil on naljakas olukord: p\u00e4ringu plaan ei ole oluliselt halvem kui eelmine, kuid tegelik loogiliste lugemiste arv on peaaegu kaks korda suurem kui t\u00e4is skaneerimise korral. Lahendus on \u2013 kui olemasolevast indeksist teha koosindeks ja teiseks v\u00e4ljaks lisada kaupade koguv\u00e4\u00e4rtus, saame j\u00e4lle 165 loogilist lugemist:<\/p>\n<pre><code class=\"sql\">CREATE INDEX IX_SalesOrderHeader_OrderDate_SubTotal ON Sales.SalesOrderHeader(OrderDate, SubTotal);\n<\/code><\/pre>\n<p>\nSeda n\u00e4idisesarja v\u00f5iks j\u00e4tkata veel kaua, kuid kaks peamist m\u00f5tet, mida soovin siin edastada, on:<\/p>\n<ul>\n<li>Iga uue kriteeriumi v\u00f5i sorteerimisj\u00e4rjekorra lisamine otsingup\u00e4ringusse v\u00f5ib oluliselt m\u00f5jutada selle t\u00e4itmise kiirus.<\/li>\n<li>Kuid kui me peame lugema vaid osa andmeid, mitte k\u00f5iki otsingutingimustele vastavaid tulemusi, on palju viise sellise p\u00e4ringu optimeerimiseks.<\/li>\n<\/ul>\n<p>\nN\u00fc\u00fcd liigume teise p\u00e4ringu juurde, millest r\u00e4\u00e4kisime alguses \u2013 see, mis arvutab kriteeriumidele vastavate kirjete arvu. V\u00f5tame sama n\u00e4ite \u2013 otsides tellimusi, mis maksavad \u00fcle 100 dollari:<\/p>\n<pre><code class=\"sql\">SELECT COUNT(1) FROM Sales.SalesOrderHeader\nWHERE SubTotal &gt; 100\n<\/code><\/pre>\n<p>\nOlemasoleva koosindeksi korral saame:<\/p>\n<p><img decoding=\"async\" alt=\"Otsingutulemuste kuvamine ja j\u00f5udlusprobleemid.\" src=\"\/wp-content\/uploads\/2020\/03\/7beab0c83a50e2d68a83a965df555ec9.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<pre><code class=\"plaintext\">Tabel 'SalesOrderHeader'. Skaneerimise arv 1, loogilised lugemised 698, f\u00fc\u00fcsilised lugemised 0, eelnevad lugemised 0, lob loogilised lugemised 0, lob f\u00fc\u00fcsilised lugemised 0, lob eelnevad lugemised 0.<\/code><\/pre>\n<p>\nKuna p\u00e4ring l\u00e4bib kogu indeksi, pole see \u00fcllatav, kuna v\u00e4li SubTotal ei ole esimesel kohal, seega ei saa p\u00e4ring seda kasutada. Probleem lahendatakse, lisades veel \u00fche indeksi v\u00e4ljale SubTotal, mis annab l\u00f5ppkokkuv\u00f5ttes juba vaid 48 loogilist lugemist.<\/p>\n<p>Saame tuua veel m\u00f5ned n\u00e4ited kandahtud arvude arvutamisest, kuid p\u00f5him\u00f5te j\u00e4\u00e4b samaks: <b>andmete osade saamine ja koguarvu arvutamine on kaks p\u00f5him\u00f5tteliselt erinevat p\u00e4ringut<\/b>, ja iga\u00fchel neist on oma meetmed optimeerimiseks. \u00dcldiselt ei saa leida indeksite kombinatsiooni, mis t\u00f6\u00f6taks m\u00f5lema p\u00e4ringu jaoks \u00fchtemoodi h\u00e4sti.<\/p>\n<p>Seega on \u00fcks olulisemaid n\u00f5udeid, mida tuleks sellise otsingulahenduse v\u00e4ljat\u00f6\u00f6tamisel t\u00e4psustada, t\u00f5esti see, kas ettev\u00f5ttele on oluline n\u00e4ha leitud objektide koguarvu. Tihti ei ole see oluline. Ja navigeerimine konkreetsete lehek\u00fcljenumbrite vahel on minu arvates v\u00e4ga kitsas lahendusala, kuna enamik lehek\u00fclgede vahetusega seotud stsenaariume n\u00e4eb v\u00e4lja nagu \"mine j\u00e4rgmisele lehele\".<\/p>\n<h2>P\u00e4evastamise variant #2<\/h2>\n<p>\nOletame, et kasutajad ei pea teadma leitud objektide koguarvu. Proovime otsingulehte lihtsustada:<\/p>\n<p><img decoding=\"async\" alt=\"Otsingutulemuste kuvamine ja j\u00f5udlusprobleemid.\" src=\"\/wp-content\/uploads\/2020\/03\/66f5ee6dc1a52f14e55ae31e05c502b2.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\nSisuliselt muutus ainult see, et ei ole v\u00f5imalik liikuda konkreetsete lehek\u00fcljenumbrite vahel ning n\u00fc\u00fcd ei pea selle tabeli jaoks teadma, kui palju lehti kokku v\u00f5iks olla. Kuid tekib k\u00fcsimus - kuidas tabel saab teada, kas j\u00e4rgmine leht on andmeid (et \u00f5igesti kuvada linki \u201eJ\u00e4rgmine\u201c)?<\/p>\n<p>Vastus on v\u00e4ga lihtne: andmebaasist saab lugeda \u00fche salvestuse rohkem, kui on vaja kuvamiseks, ja see \"\u00fclem\u00e4\u00e4rane\" salvestus n\u00e4itab, kas j\u00e4rgmine hulk andmeid on olemas. Seega, et saada \u00fcks andmeleht, tuleb teha vaid \u00fcks p\u00e4ring, mis oluliselt parandab j\u00f5udlust ja lihtsustab sellise funktsiooni toetamist. Mul oli praktikas juhtum, kus koguarvust loobumine kiirendas tulemuste v\u00e4ljundit 4-5 korda.<\/p>\n<p>Selle l\u00e4henemise jaoks on mitu liidese varianti: nupud \u201etagasi\u201c ja \u201eedasi\u201c, nagu \u00fclaltoodud n\u00e4ites, nupp \u201elae rohkem\u201c, mis lihtsalt lisab uusi andmeid kuvatud tulemustele, \u201el\u00f5putu kerimine\u201c, mis t\u00f6\u00f6tab nagu \u201elae rohkem\u201c, kuid signaal j\u00e4rgmise hulga saamiseks on kasutaja kerimine k\u00f5igi kuvatud tulemusteni l\u00f5puni. Milline visualiseerimislahendus iganes, andmete valimise p\u00f5him\u00f5te j\u00e4\u00e4b samaks.<\/p>\n<h2>P\u00e4evastamise rakendamise n\u00fcansid<\/h2>\n<p>\nK\u00f5ik \u00fclaltoodud p\u00e4ringute n\u00e4ited kasutavad l\u00e4henemist \u201eoffset + count\u201c, kus p\u00e4ringus on n\u00e4idatud, milliselt realt alustada ja kui palju ridu tagasi saada. Esiteks vaatame, kuidas oleks parem edastada parameetreid sel juhul. Praktikas olen kohtunud mitme meetodiga:<\/p>\n<ul>\n<li>Tellige lehe j\u00e4rjekorranumber (pageIndex), lehe suurus (pageSize).<\/li>\n<li>Tellige esimese salvestuse j\u00e4rjekorranumber, mida tuleb tagasi anda (startIndex), maksimaalne salvestuste arv tulemuses (count).<\/li>\n<li>Tellige esimese salvestuse j\u00e4rjekorranumber, mida tuleb tagasi anda (startIndex), viimase salvestuse j\u00e4rjekorranumber, mida tuleb tagasi anda (endIndex).<\/li>\n<\/ul>\n<p>\nEsmapilgul v\u00f5ib tunduda, et see on nii elementaarne, et vahet ei ole. Kuid see ei ole t\u00f5si - k\u00f5ige mugavam ja universaalsem variant on teine (startIndex, count). Sellel on mitu p\u00f5hjust:<\/p>\n<ul>\n<li>Eelneva '+1' salvestuse lugemise l\u00e4henemise puhul on esimene variant (pageIndex ja pageSize) \u00e4\u00e4rmiselt ebamugav. N\u00e4iteks soovime kuvada lehe kaupa 50 salvestust. Vastavalt \u00fclaltoodud algoritmile tuleb lugeda \u00fche salvestuse rohkem, kui vajalik. Kui see \u201e+1\u201c ei ole serverisse sisse ehitatud, peame esimeselt lehelt k\u00fcsima salvestusi 1 kuni 51, teiselt - 51 kuni 101 jne. Kui lehe suurus on 51 ja suurendame pageIndex, naaseb teine leht 52 kuni 102 jne. Seega on esimese variandi ainus viis j\u00e4rgmise lehe nuppude korrektseks rakendamiseks, et serverisse sisse ehitada \u201e\u00fcleliigsete\u201c ridade lugemine, mis oleks v\u00e4ga ebaselge n\u00fcanss.<\/li>\n<li>Kolmas variant on t\u00e4ielikult m\u00f5tetu, kuna enamikus andmebaasides tuleb p\u00e4ringute t\u00e4itmiseks ikkagi edastada salvestuste arv, mitte viimase salvestuse indeks. Olgu startIndex'i lahutamine endIndex'ist elementaarne aritmeetiline toiming, kuid see on siin \u00fcleliigne.<\/li>\n<\/ul>\n<p>\nN\u00fc\u00fcd tuleks kirjeldada p\u00e4evastamise rakendamise puudusi l\u00e4henemisega \"offset + count\":<\/p>\n<ul>\n<li>Iga j\u00e4rgmise lehe saamine on kulukam ja aeglasem kui eelmine, kuna andmebaas peab ikkagi l\u00e4bima k\u00f5ik salvestused \"algusest\" vastavalt otsingukriteeriumidele ja sortimisele ning seej\u00e4rel peatuma \u00f5igel fraktsioonil.<\/li>\n<li>Kaugel k\u00f5ik andmebaasid v\u00f5ivad seda l\u00e4henemist toetada.<\/li>\n<\/ul>\n<p>\nAlternatiivid on olemas, kuid need pole ka ideaalsed. Esimese sellise l\u00e4henemise nimi on \"keyset paging\" v\u00f5i \"seek method\", mis t\u00e4hendab j\u00e4rgmist: p\u00e4rast osade saamist saab salvestada v\u00e4\u00e4rtused v\u00e4ljadest viimases salvestuses lehel ja seej\u00e4rel kasutada neid j\u00e4rgmise osa saamiseks. N\u00e4iteks sooritasime sellise p\u00e4ringu:<\/p>\n<pre><code class=\"sql\">SELECT * FROM Sales.SalesOrderHeader\nORDER BY OrderDate DESC\nOFFSET 0 ROWS\nFETCH NEXT 50 ROWS ONLY\n<\/code><\/pre>\n<p>\nJa viimasest \u00fclesandest saime tellimuse kuup\u00e4eva v\u00e4\u00e4rtuse '2014-06-29'. Seega j\u00e4rgmise lehe saamiseks v\u00f5iks proovida j\u00e4rgmist:<\/p>\n<pre><code class=\"sql\">SELECT * FROM Sales.SalesOrderHeader\nWHERE OrderDate &lt; &#039;2014-06-29&#039;\nORDER BY OrderDate DESC\nOFFSET 0 ROWS\nFETCH NEXT 50 ROWS ONLY\n<\/code><\/pre>\n<p>\nProbleem on selles, et OrderDate ei ole unikaalne v\u00e4li ja eespool toodud tingimus j\u00e4tab suure t\u00f5en\u00e4osusega paljusid vajalikke ridu vahele. Selle p\u00e4ringu selgitamiseks tuleb tingimusse lisada unikaalne v\u00e4li (eeldame, et 75074 on esimese osa viimane primaarv\u00f5tme v\u00e4\u00e4rtus):<\/p>\n<pre><code class=\"sql\">SELECT * FROM Sales.SalesOrderHeader\nWHERE (OrderDate = '2014-06-29' AND SalesOrderID &lt; 75074)\n   OR (OrderDate &lt; &#039;2014-06-29&#039;)\nORDER BY OrderDate DESC, SalesOrderID DESC\nOFFSET 0 ROWS\nFETCH NEXT 50 ROWS ONLY\n<\/code><\/pre>\n<p>\nSee variant t\u00f6\u00f6tab \u00f5igesti, kuid \u00fcldiselt on seda keeruline optimeerida, kuna tingimus sisaldab operaatorit OR. Kui OrderDate'i suurenedes suureneb ka esmase v\u00f5tme v\u00e4\u00e4rtus, saab tingimust lihtsustada, j\u00e4ttes alles ainult filtrit SalesOrderID alusel. Kuid kui esmase v\u00f5tme v\u00e4\u00e4rtuste ja tulemuste sortimise aluseks oleva v\u00e4lja vahel ei ole ranget korrelatsiooni, siis enamikus andmebaasihalduss\u00fcsteemides ei \u00f5nnestu seda OR-i v\u00e4ltida. \u00dcks tuntud erand on PostgreSQL, kus tuplite v\u00f5rdlemist toetatakse t\u00e4ielikult, ja eelnev tingimus saab kirjutada j\u00e4rgmiselt: 'WHERE (OrderDate, SalesOrderID) &lt; (&#039;2014-06-29&#039;, 75074)&#039;. Kui selline koosnev v\u00f5ti kahe v\u00e4lja j\u00e4rgi olemas on, peaks see p\u00e4ring olema piisavalt kerge.<\/p>\n<p>Teine alternatiivne l\u00e4henemine v\u00f5ib olla n\u00e4iteks <noindex><a rel=\"nofollow\" href=\"https:\/\/www.elastic.co\/guide\/en\/elasticsearch\/reference\/6.8\/search-request-scroll.html\">ElasticSearch scroll API<\/a><\/noindex> v\u00f5i <noindex><a rel=\"nofollow\" href=\"https:\/\/medium.com\/@gary.strange\/understanding-cosmosdb-continuation-tokens-hasmoreresults-and-connectionpolicy-requesttimeouts-3ed1fadfa81d\">Cosmos DB<\/a><\/noindex> \u2014 kui p\u00e4ring tagastab andmete k\u00f5rval erilise identifikaatori, millega saab j\u00e4rgmise andmepartii. Kui see identifikaator on piiramatu elueaga (nagu Comsos DB-s), on see suurep\u00e4rane viise lehtede vaheliste j\u00e4rjestikuste \u00fcleminekute rakendamiseks (eelnevalt mainitud variant #2). Selle v\u00f5imalikud puudused: seda ei toetata kaugeltki k\u00f5igis andmebaasides; j\u00e4rgmise partii saamiseks saadud identifikaatoril v\u00f5ib olla piiratud eluaeg, mis \u00fcldiselt ei sobi kasutajaga suhtlemiseks (nagu n\u00e4iteks ElasticSearch scroll API).<\/p>\n<h2>Keeruline filtreerimine<\/h2>\n<p>\nTeeme \u00fclesande veelgi keerulisemaks. Oletame, et on tekkinud n\u00f5udmine rakendada nn faceted search-i, mis on internetipoodidest h\u00e4sti tuntud. Eelnevad n\u00e4ited, mis p\u00f5hinevad tellimustabelil, ei ole sel juhul eriti n\u00e4itlikud, seega liigume AdvantureWorks andmebaasi toote tabelisse:<\/p>\n<p><img decoding=\"async\" alt=\"Otsingutulemuste kuvamine ja j\u00f5udlusprobleemid.\" src=\"\/wp-content\/uploads\/2020\/03\/070890a3cb79de3edc69b60b5300efe7.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\nMis on faceted search'i idee? Selles seisneb, et iga filtri elemendi jaoks kuvatakse arvu, mis vastab sellele kriteeriumile. <i>v\u00f5ttes arvesse k\u00f5iki teisi kategooriaid valitud filtreid.<\/i>.<\/p>\n<p>N\u00e4iteks, kui valime antud n\u00e4ites kategooria Jalgrattad ja v\u00e4rv Must, kuvab tabel ainult musta v\u00e4rvi jalgrattaid, kuid samas:<\/p>\n<ul>\n<li>Iga 'Kategooriad' grupi kriteeriumi jaoks kuvatakse arvu musta v\u00e4rvi tooteid, mis kuuluvad sellesse kategooriasse.<\/li>\n<li>Iga 'V\u00e4rvid' grupi kriteeriumi jaoks kuvatakse musta v\u00e4rvi jalgrataste arvu.<\/li>\n<\/ul>\n<p>\nSiin on n\u00e4ide selliste tingimuste jaoks tulemuste kuvamisest:<\/p>\n<p><img decoding=\"async\" alt=\"Otsingutulemuste kuvamine ja j\u00f5udlusprobleemid.\" src=\"\/wp-content\/uploads\/2020\/03\/7c8ec4d8b427f1f59f0129afebe74b08.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\nKui lisaks valida kategooria 'Riided', kuvab tabel ka musta v\u00e4rvi riideid, mis on laos. Mustade toodete arvu sektsioonis 'V\u00e4rv' arvutatakse vastavalt uutele tingimustele \u00fcmber, kuid 'Kategooriad' sektsioonis ei muutu enam midagi... Loodan, et neid n\u00e4iteid piisab, et m\u00f5ista faceted search'i tuttavat t\u00f6\u00f6protsessi.<\/p>\n<p>N\u00fc\u00fcd kujutame ette, kuidas seda saab rakendada relatsioonilises andmebaasis. Iga kriteeriumigrupp, nagu Kategooria ja V\u00e4rv, vajab eraldi p\u00e4ringut:<\/p>\n<pre><code class=\"sql\">SELECT pc.ProductCategoryID, pc.Name, COUNT(1) FROM Production.Product p\n  INNER JOIN Production.ProductSubcategory ps ON p.ProductSubcategoryID = ps.ProductSubcategoryID\n  INNER JOIN Production.ProductCategory pc ON ps.ProductCategoryID = pc.ProductCategoryID\nWHERE p.Color = 'Black'\nGROUP BY pc.ProductCategoryID, pc.Name\nORDER BY COUNT(1) DESC\n<\/code><\/pre>\n<p>\n<img decoding=\"async\" alt=\"Otsingutulemuste kuvamine ja j\u00f5udlusprobleemid.\" src=\"\/wp-content\/uploads\/2020\/03\/3b59b68ce934c4ec1630ec649e68ccdb.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<pre><code class=\"sql\">SELECT Color, COUNT(1) FROM Production.Product p\n  INNER JOIN Production.ProductSubcategory ps ON p.ProductSubcategoryID = ps.ProductSubcategoryID\nWHERE ps.ProductCategoryID = 1 --Jalgrattad\nGROUP BY Color\nORDER BY COUNT(1) DESC\n<\/code><\/pre>\n<p>\n<img decoding=\"async\" alt=\"Otsingutulemuste kuvamine ja j\u00f5udlusprobleemid.\" src=\"\/wp-content\/uploads\/2020\/03\/82e1e6ab0fae683d383e3fecf4e3a15a.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\nMis on valesti selle lahendusega? V\u00e4ga lihtsalt \u2014 see ei skaala h\u00e4sti. Iga filtrisegment vajab eraldi p\u00e4ringut koguste arvestamiseks ja need p\u00e4ringud ei ole eriti kerged. Internetipoodides v\u00f5ib m\u00f5nes kategoorias olla ka mitu tosinat filtrisegmenti, mis v\u00f5ib osutuda t\u00f5siseks probleemiks j\u00f5udlusele.<\/p>\n<p>Tavaliselt pakuvad mulle p\u00e4rast neid v\u00e4iteid m\u00f5ned lahendused, nimelt:<\/p>\n<ul>\n<li>Kombineerida k\u00f5ik koguste arvutused \u00fcheks p\u00e4ringuks. Tehniliselt on see v\u00f5imalik s\u00f5na UNION abil, kuid see ei aita eriti j\u00f5udluse osas \u2014 andmebaasil tuleb ikkagi \"nullist\" iga fragment k\u00e4ivitada.<\/li>\n<li>K\u00fclastusmahtude vahem\u00e4lestamine. Seda pakutakse mulle praktiliselt igal korral, kui kirjeldan probleemi. Probleemi keerukus on see, et see on tavaliselt sisuliselt ebareaalne. Oletame, et meil on 10 \u201efassaadi\u201c, milles on 5 v\u00e4\u00e4rtust. See on v\u00e4ga \u201emodest\u201c olukord v\u00f5rreldes sellega, mida v\u00f5ib n\u00e4ha samades veebipoodides. \u00dche fassaadi elemendi valik m\u00f5jutab 9 teist, teisis\u00f5nu, iga kriteeriumi kombinatsiooni jaoks v\u00f5ivad kogused olla erinevad. Kokku on meie n\u00e4ites 50 kriteeriast, mida kasutaja saab valida, seega on v\u00f5imalikke kombinatsioone 250. Sellise andmemahtu t\u00e4itmiseks ei piisa ei m\u00e4lu ega ajast. Siinkohal v\u00f5ib vastu v\u00e4ita, et mitte k\u00f5ik kombinatsioonid pole reaalsed ja kasutaja valib harva rohkem kui 5-10 kriteeriat. Jah, saab teha laiskade laadimist ja koguste vahem\u00e4lestamist ainult neile, mis kunagi on valitud, kuid mida rohkem valikuv\u00f5imalusi on, seda v\u00e4hem efektiivne on selline vahem\u00e4lu ning seda silmatorkavamad on probleemid vastamisaegadega (eriti kui andmestik muutub regulaarselt).<\/li>\n<\/ul>\n<p>\n\u00d5nneks on sellisel \u00fclesandel ammu olemas piisavalt t\u00f5husad lahendused, mis t\u00f6\u00f6tavad ennustatavasti suurte andmemahtudega. Iga\u00fche jaoks on m\u00f5istlik eraldada fassaadide \u00fcmberarvutamine ja tulemuste lehe saamine kahe paralleelse p\u00e4ringu kaudu serverisse ning korraldada kasutajaliides selliselt, et fassaadide andmete laadimine \u201eei sega\u201d otsingutulemuste kuvamist.<\/p>\n<ul>\n<li>Kutsuda fassaadide t\u00e4ielikku \u00fcmberarvutamist nii harva kui v\u00f5imalik. N\u00e4iteks mitte \u00fcmber arvutada k\u00f5ike igal otsingukriteeriumide muutmisel, vaid leida \u00fcldine tulemuste arv, mis vastab praegustele tingimustele ning pakkuda kasutajale nende kuvamist: \u201eleiti 1425 kirjet, kas n\u00e4idata?\u201c Kasutaja v\u00f5ib kas j\u00e4tkata otsingutingimuste muutmist v\u00f5i vajutada nuppu \u201en\u00e4ita\u201c. Ainult teisel juhul teostatakse k\u00f5ik p\u00e4ringud tulemuste saamiseks ja fassaadide koguste \u00fcmberarvutamiseks. Sellega seoses, nagu on lihtne m\u00e4rgata, tuleb tegeleda p\u00e4ringuga \u00fcldarvu saamiseks ja selle optimeerimiseks. Seda l\u00e4henemist v\u00f5ib leida paljusid v\u00e4ikeseid veebipoodidest. Ilmselgelt ei ole see lahendus selle probleemi jaoks, kuid lihtsates olukordades v\u00f5ib see olla hea kompromiss.<\/li>\n<li>Kasutada otsingumootorit tulemuste otsimiseks ja fassaadide arvu lugemiseks, nagu Solr, ElasticSearch, Sphinx ja teised. K\u00f5ik need on loodud \u201efassaadide\u201c genereerimiseks ja teevad seda piisavalt efektiivselt, kasutades p\u00f6\u00f6rdindeksi. Kuidas otsingus\u00fcsteemid t\u00f6\u00f6tavad, miks need on sellistes olukordades efektiivsemad kui \u00fcldotstarbelised andmebaasid, millised on parimad praktikad ja varjatud probleemid \u2014 see on eraldi artikli teema. Siin tahan r\u00f5hutada, et otsingumootor ei saa olla peamise andmehoidla asendaja, seda kasutatakse t\u00e4iendava vahendina: k\u00f5ik peamises andmebaasis toimuvad muutused, mis m\u00f5jutavad otsingut, s\u00fcnkroniseeritakse otsinguindeksisse; otsingumehhanism suhtleb tavaliselt ainult otsingumootoriga ega p\u00f6\u00f6rdu peamise andmebaasi poole. \u00dcks k\u00f5ige olulisemaid aspekte siin on, kuidas korraldada see s\u00fcnkroniseerimine usaldusv\u00e4\u00e4rselt. K\u00f5ik s\u00f5ltub n\u00f5uetest \u201ereaktsiooniaja\u201d osas. Kui aeg peamise andmebaasi muudatuse ja selle \u201epeegeldumise\u201c vahel otsingus ei ole kriitiline, saab teha teenuse, mis korra paari minuti jooksul otsib hiljuti muudetud kirjeid ja indekseerib need. Kui soovitakse minimaalset v\u00f5imalikku reaktsiooniaega, saab rakendada midagi sellist nagu <noindex><a rel=\"nofollow\" href=\"https:\/\/microservices.io\/patterns\/data\/transactional-outbox.html\">transactional outbox<\/a><\/noindex> uuenduste saatmiseks otsinguteenusesse.<\/li>\n<\/ul>\n<p><\/p>\n<h2>J\u00e4reldused<\/h2>\n<p><\/p>\n<ol>\n<li>Serveripoolse lehek\u00fcljenduse teostamine on t\u00f5sine keerukus, ja selle rakendamine on m\u00f5istlik ainult kiiresti kasvavate v\u00f5i lihtsalt suurte andmehulkade puhul. Kuidas hinnata, mis on \u201esuur\u201d v\u00f5i \u201ekiiresti kasvav\u201d \u2014 absoluutset t\u00e4pset retsept ei ole, kuid ma j\u00e4rgiksin j\u00e4rgmist l\u00e4henemist:\n<ul>\n<li>Kui andmekogu t\u00e4ielik saamine, v\u00f5ttes arvesse serveri aega ja andmete edastamist v\u00f5rgus, mahub normaalselt j\u00f5udluse n\u00f5uetesse \u2014 serveripoolse lehek\u00fcljenduse rakendamiseks pole m\u00f5tet.<\/li>\n<li>V\u00f5ib juhtuda, et l\u00e4hitulevikus pole j\u00f5udlusprobleeme, kuna andmeid on v\u00e4he, kuid andmekogu kasvab pidevalt. Kui m\u00f5ni andmehulk ei pruugi tulevikus enam rahuldada eelmist punkti \u2014 v\u00f5iks serveripoolset lehek\u00fcljendust kohe kavandada.<\/li>\n<\/ul>\n<\/li>\n<li>Kui \u00e4ri poolelt pole ranged n\u00f5uded \u00fcldise tulemuste arvu kuvamiseks v\u00f5i lehek\u00fcljenumbrite kuvamiseks, ja teie s\u00fcsteemis ei ole otsingumootorit \u2014 on parem neid punkte mitte rakendada ja kaaluda varianti #2.<\/li>\n<li>Kui on selged n\u00f5uded faceted search'ile, siis on teil kaks v\u00f5imalust, et mitte ohverdada tootlikkust:\n<ul>\n<li>\u00c4rge arvutage k\u00f5iki arve iga otsingukriteeriumi muutmise korral.<\/li>\n<li>Kasutage otsingumootoreid nagu Solr, ElasticSearch, Sphinx ja teised. Kuid on oluline m\u00f5ista, et see ei saa asendada p\u00f5hitooriku andmebaasi ning seda tuleks kasutada lisandina peamise salvestuse jaoks otsingute \u00fclesannete lahendamiseks. <\/li>\n<\/ul>\n<\/li>\n<li>Samuti on m\u00f5istlik jagada otsingutulemuste lehe saamine ja arvude arvestamine kaheks paralleelseks p\u00e4ringuks. Arvude arvestamine v\u00f5ib v\u00f5tta rohkem aega kui tulemuste saamine, samas kui tulemused on kasutaja jaoks olulisemad.<\/li>\n<li>Kui kasutate SQL-andmebaasi otsimiseks, siis peab k\u00f5ik koodimuudatused, mis puudutavad seda osa, olema hoolikalt testitud tootlikkuse osas vastava andmemahtu (mis \u00fcletab ''elava'' andmebaasi mahu) suhtes. Samuti on soovitatav j\u00e4lgida p\u00e4ringute t\u00e4itmise aega k\u00f5igis andmebaasi instantsides, eriti - ''elavas'' andmebaasis. Isegi kui arendusetapis k\u00f5ik p\u00e4ringute plaanid olid head, v\u00f5ib andmemahtu kasvades olukord oluliselt muutuda.<\/li>\n<\/ol>\n<p>Allikas: <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/epam_systems\/blog\/493438\/\">habr.com<\/a> <\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>\u041e\u0434\u0438\u043d \u0438\u0437 \u0442\u0438\u043f\u043e\u0432\u044b\u0445 \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u0435\u0432 \u0432\u043e \u0432\u0441\u0435\u0445 \u043f\u0440\u0438\u0432\u044b\u0447\u043d\u044b\u0445 \u043d\u0430\u043c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f\u0445 \u2014 \u043f\u043e\u0438\u0441\u043a \u0434\u0430\u043d\u043d\u044b\u0445 \u043f\u043e \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u044b\u043c \u043a\u0440\u0438\u0442\u0435\u0440\u0438\u044f\u043c \u0438 \u0432\u044b\u0432\u043e\u0434 \u0438\u0445 \u0432 \u0443\u0434\u043e\u0431\u043d\u043e\u043c \u0434\u043b\u044f \u0447\u0442\u0435\u043d\u0438\u044f \u0432\u0438\u0434\u0435. \u0422\u0443\u0442 \u0436\u0435 \u043c\u043e\u0433\u0443\u0442 \u0431\u044b\u0442\u044c \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u043f\u043e \u0441\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u043a\u0435, \u0433\u0440\u0443\u043f\u043f\u0438\u0440\u043e\u0432\u043a\u0435, \u043f\u043e\u0441\u0442\u0440\u0430\u043d\u0438\u0447\u043d\u043e\u043c\u0443 \u0432\u044b\u0432\u043e\u0434\u0443. \u0417\u0430\u0434\u0430\u0447\u0430, \u043f\u043e \u0438\u0434\u0435\u0435, \u0442\u0440\u0438\u0432\u0438\u0430\u043b\u044c\u043d\u0430\u044f, \u043d\u043e \u043f\u0440\u0438 \u0435\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u0438 \u043c\u043d\u043e\u0433\u0438\u0435 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0438 \u0434\u0435\u043b\u0430\u044e\u0442 \u0440\u044f\u0434 \u043e\u0448\u0438\u0431\u043e\u043a, \u0438\u0437-\u0437\u0430 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u043f\u043e\u0442\u043e\u043c \u0441\u0442\u0440\u0430\u0434\u0430\u0435\u0442 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c. \u041f\u043e\u043f\u0440\u043e\u0431\u0443\u0435\u043c \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0435 [&hellip;]<\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"author":1,"featured_media":75531,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[688],"tags":[],"class_list":["post-75530","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.0.1 - aioseo.com -->\n\t<meta name=\"description\" content=\"\u041e\u0434\u0438\u043d \u0438\u0437 \u0442\u0438\u043f\u043e\u0432\u044b\u0445 \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u0435\u0432 \u0432\u043e \u0432\u0441\u0435\u0445 \u043f\u0440\u0438\u0432\u044b\u0447\u043d\u044b\u0445 \u043d\u0430\u043c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f\u0445 \u2014 \u043f\u043e\u0438\u0441\u043a \u0434\u0430\u043d\u043d\u044b\u0445 \u043f\u043e \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u044b\u043c \u043a\u0440\u0438\u0442\u0435\u0440\u0438\u044f\u043c \u0438 \u0432\u044b\u0432\u043e\u0434 \u0438\u0445 \u0432 \u0443\u0434\u043e\u0431\u043d\u043e\u043c \u0434\u043b\u044f \u0447\u0442\u0435\u043d\u0438\u044f \u0432\u0438\u0434\u0435.\" \/>\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\/et\/blog\/administrirovanie\/vyvod-rezultatov-poiska-i-problemy-s-proizvoditelnostyu\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.0.1\" \/>\n\t\t<meta property=\"og:locale\" content=\"et_EE\" \/>\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\u0412\u044b\u0432\u043e\u0434 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u0432 \u043f\u043e\u0438\u0441\u043a\u0430 \u0438 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b \u0441 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c\u044e | ProHoster\" \/>\n\t\t<meta property=\"og:description\" content=\"\u041e\u0434\u0438\u043d \u0438\u0437 \u0442\u0438\u043f\u043e\u0432\u044b\u0445 \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u0435\u0432 \u0432\u043e \u0432\u0441\u0435\u0445 \u043f\u0440\u0438\u0432\u044b\u0447\u043d\u044b\u0445 \u043d\u0430\u043c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f\u0445 \u2014 \u043f\u043e\u0438\u0441\u043a \u0434\u0430\u043d\u043d\u044b\u0445 \u043f\u043e \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u044b\u043c \u043a\u0440\u0438\u0442\u0435\u0440\u0438\u044f\u043c \u0438 \u0432\u044b\u0432\u043e\u0434 \u0438\u0445 \u0432 \u0443\u0434\u043e\u0431\u043d\u043e\u043c \u0434\u043b\u044f \u0447\u0442\u0435\u043d\u0438\u044f \u0432\u0438\u0434\u0435.\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/et\/blog\/administrirovanie\/vyvod-rezultatov-poiska-i-problemy-s-proizvoditelnostyu\" \/>\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=\"2020-03-26T17:42:23+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2020-03-26T17:42:23+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\udd47Otsingutulemuste v\u00e4ljund ja tootlikkuse probleemid | ProHoster","description":"\u041e\u0434\u0438\u043d \u0438\u0437 \u0442\u0438\u043f\u043e\u0432\u044b\u0445 \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u0435\u0432 \u0432\u043e \u0432\u0441\u0435\u0445 \u043f\u0440\u0438\u0432\u044b\u0447\u043d\u044b\u0445 \u043d\u0430\u043c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f\u0445 \u2014 \u043f\u043e\u0438\u0441\u043a \u0434\u0430\u043d\u043d\u044b\u0445 \u043f\u043e \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u044b\u043c \u043a\u0440\u0438\u0442\u0435\u0440\u0438\u044f\u043c \u0438 \u0432\u044b\u0432\u043e\u0434 \u0438\u0445 \u0432 \u0443\u0434\u043e\u0431\u043d\u043e\u043c \u0434\u043b\u044f \u0447\u0442\u0435\u043d\u0438\u044f \u0432\u0438\u0434\u0435.","canonical_url":"https:\/\/prohoster.info\/et\/blog\/administrirovanie\/vyvod-rezultatov-poiska-i-problemy-s-proizvoditelnostyu","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"et_EE","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\u0412\u044b\u0432\u043e\u0434 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u0432 \u043f\u043e\u0438\u0441\u043a\u0430 \u0438 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b \u0441 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c\u044e | ProHoster","og:description":"\u041e\u0434\u0438\u043d \u0438\u0437 \u0442\u0438\u043f\u043e\u0432\u044b\u0445 \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u0435\u0432 \u0432\u043e \u0432\u0441\u0435\u0445 \u043f\u0440\u0438\u0432\u044b\u0447\u043d\u044b\u0445 \u043d\u0430\u043c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f\u0445 \u2014 \u043f\u043e\u0438\u0441\u043a \u0434\u0430\u043d\u043d\u044b\u0445 \u043f\u043e \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u044b\u043c \u043a\u0440\u0438\u0442\u0435\u0440\u0438\u044f\u043c \u0438 \u0432\u044b\u0432\u043e\u0434 \u0438\u0445 \u0432 \u0443\u0434\u043e\u0431\u043d\u043e\u043c \u0434\u043b\u044f \u0447\u0442\u0435\u043d\u0438\u044f \u0432\u0438\u0434\u0435.","og:url":"https:\/\/prohoster.info\/et\/blog\/administrirovanie\/vyvod-rezultatov-poiska-i-problemy-s-proizvoditelnostyu","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":"2020-03-26T17:42:23+00:00","article:modified_time":"2020-03-26T17:42:23+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"75530","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":null,"breadcrumb_settings":null,"limit_modified_date":false,"reviewed_by":null,"ai":null,"created":"2021-02-28 17:55:26","updated":"2022-10-02 02:12:16","focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"gt_translate_keys":[{"key":"link","format":"url"}],"_links":{"self":[{"href":"https:\/\/prohoster.info\/et\/wp-json\/wp\/v2\/posts\/75530","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/et\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/et\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/et\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/et\/wp-json\/wp\/v2\/comments?post=75530"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/et\/wp-json\/wp\/v2\/posts\/75530\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/et\/wp-json\/wp\/v2\/media\/75531"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/et\/wp-json\/wp\/v2\/media?parent=75530"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/et\/wp-json\/wp\/v2\/categories?post=75530"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/et\/wp-json\/wp\/v2\/tags?post=75530"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}