{"id":79893,"date":"2020-05-01T13:43:12","date_gmt":"2020-05-01T11:43:12","guid":{"rendered":"https:\/\/prohoster.info\/blog\/administrirovanie\/postgresql-i-jdbc-vyzhimaem-vse-soki-vladimir-sitnikov"},"modified":"2020-05-01T13:43:12","modified_gmt":"2020-05-01T11:43:12","slug":"postgresql-i-jdbc-vyzhimaem-vse-soki-vladimir-sitnikov","status":"publish","type":"post","link":"https:\/\/prohoster.info\/et\/blog\/administrirovanie\/postgresql-i-jdbc-vyzhimaem-vse-soki-vladimir-sitnikov","title":{"rendered":"PostgreSQL ja JDBC pigistame v\u00e4lja iga tilka. Vladimir Sitnikov","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p><strong>Palun tutvuge 2016. aasta alguses Vladimir Sitnikovi ettekande \"PostgreSQL ja JDBC - pigistame v\u00e4lja k\u00f5ik mahlad\" t\u00f5lgendusega.<\/strong><\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"PostgreSQL ja JDBC pigistame v\u00e4lja iga tilka. Vladimir Sitnikov\" src=\"\/wp-content\/uploads\/2020\/05\/9d94c8a024bd2821e431c525aae0127d.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<p><img decoding=\"async\" alt=\"PostgreSQL ja JDBC pigistame v\u00e4lja iga tilka. Vladimir Sitnikov\" src=\"\/wp-content\/uploads\/2020\/05\/030666abda53aa388b1cb1d0c46a7524.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Tere p\u00e4eva! Minu nimi on Vladimir Sitnikov. T\u00f6\u00f6sklen ettev\u00f5ttes NetCracker juba 10 aastat. Ja peamiselt tegelen tootlikkuse k\u00fcsimustega. K\u00f5ik, mis on seotud Java ja SQL-iga, on see, mida ma armastan. <\/p>\n<p><\/p>\n<p>Ja t\u00e4na r\u00e4\u00e4gin teile sellest, millega me ettev\u00f5ttes silmitsi seisime, kui hakkasime PostgreSQL kasutama andmebaasiserverina. Peamiselt t\u00f6\u00f6tame Java'ga. Kuid see, millest ma t\u00e4na r\u00e4\u00e4gin, ei seondu vaid Java'ga. Kogemus on n\u00e4idanud, et sama juhtub ka teistes keeltes. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"PostgreSQL ja JDBC pigistame v\u00e4lja iga tilka. Vladimir Sitnikov\" src=\"\/wp-content\/uploads\/2020\/05\/b01a214d782c7e32797a6c6466457979.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>R\u00e4\u00e4gime j\u00e4rgmistest asjadest:<\/p>\n<p><\/p>\n<ul>\n<li>andmete valimisest. <\/li>\n<li>Andmete salvestamisest. <\/li>\n<li>Ning tootlikkusest. <\/li>\n<li>Ja ka peidetud kaevandustest, mis seal on. <\/li>\n<\/ul>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"PostgreSQL ja JDBC pigistame v\u00e4lja iga tilka. Vladimir Sitnikov\" src=\"\/wp-content\/uploads\/2020\/05\/57da0c6aa4bb62e1beb77160f5aee7e7.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Alustame lihtsast k\u00fcsimusest. Valime tabelist \u00fche rea primaarv\u00f5tme alusel. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"PostgreSQL ja JDBC pigistame v\u00e4lja iga tilka. Vladimir Sitnikov\" src=\"\/wp-content\/uploads\/2020\/05\/d5fcb1172aef402a87064498bf8a5218.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Andmebaas asub samal hostil. Ja kogu see tegevus kestab 20 millisekundit.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"PostgreSQL ja JDBC pigistame v\u00e4lja iga tilka. Vladimir Sitnikov\" src=\"\/wp-content\/uploads\/2020\/05\/103b7f9736b82a3313491b2f0d2a5824.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Need 20 millisekundit on v\u00e4ga palju. Kui teil on 100 sellist p\u00e4ringut, siis kulutate aega sekundites, et neid p\u00e4ringuid t\u00f6\u00f6deldada, st raiskate aega.<\/p>\n<p><\/p>\n<p>Me ei soovi seda teha ja vaatame, mida andmebaas meile selleks pakub. Andmebaas pakub meile kahte valikut p\u00e4ringute t\u00e4itmiseks. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"PostgreSQL ja JDBC pigistame v\u00e4lja iga tilka. Vladimir Sitnikov\" src=\"\/wp-content\/uploads\/2020\/05\/b467e86a0f8c4c32cea182fe27a28e6e.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Esimene variant on lihtne p\u00e4ring. Miks see on hea? Sellega on see, et me v\u00f5tame selle ja saadame, ja ei midagi enamat. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"PostgreSQL ja JDBC pigistame v\u00e4lja iga tilka. Vladimir Sitnikov\" src=\"\/wp-content\/uploads\/2020\/05\/7e333a62ba68feb0781ff96e39486591.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p><noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/pgjdbc\/pgjdbc\/pull\/478\">https:\/\/github.com\/pgjdbc\/pgjdbc\/pull\/478<\/a><\/noindex><\/p>\n<p><\/p>\n<p>Andmebaasil on veel ka t\u00e4iustatud p\u00e4ring, mis on keerulisem, kuid funktsionaalsem. V\u00f5ib eraldi saata p\u00e4ringu parsimiseks, t\u00e4itmiseks, muutujate \u00fchendamiseks jne. <\/p>\n<p><\/p>\n<p>Super t\u00e4iustatud p\u00e4ring \u2013 seda me ei k\u00e4sitle praeguses ettekandes. V\u00f5ib-olla tahame andmebaasilt midagi ja meil on soovide nimekiri, mis on mingil kujul koostatud, st see, mida me soovime, kuid ei ole praegu ega ka l\u00e4hima aasta jooksul v\u00f5imalik. Seet\u00f5ttu kirjutasime selle lihtsalt \u00fcles ja k\u00e4ime peamisi inimesi pommitamas.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"PostgreSQL ja JDBC pigistame v\u00e4lja iga tilka. Vladimir Sitnikov\" src=\"\/wp-content\/uploads\/2020\/05\/19094729074fd28c5b9f236833a9a266.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Aga see, mida me saame teha, on lihtne p\u00e4ring ja t\u00e4iustatud p\u00e4ring.<\/p>\n<p><\/p>\n<p>Mis on iga l\u00e4henemise erip\u00e4ra? <\/p>\n<p><\/p>\n<p>Lihtsat p\u00e4ringut on hea kasutada \u00fchekordseks t\u00e4itmiseks. T\u00e4idetud ja unustatud. Probleem on selles, et see ei toeta binaarset andmevormingut, st m\u00f5ned k\u00f5rge j\u00f5udlusega s\u00fcsteemid ei sobi selleks.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"PostgreSQL ja JDBC pigistame v\u00e4lja iga tilka. Vladimir Sitnikov\" src=\"\/wp-content\/uploads\/2020\/05\/062c0e45cefd91ece331a306a7651bde.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Pikendatud p\u00e4ring - aitab s\u00e4\u00e4sta aega parsimisel. See on see, mida me tegime ja hakkasime kasutama. See on meid \u00e4\u00e4rmiselt aidanud. Siin on mitte ainult s\u00e4\u00e4st parsimisel. On olemas ka andmete edastamise s\u00e4\u00e4st. Andmete edastamine binaarses formaadis on oluliselt efektiivsem. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"PostgreSQL ja JDBC pigistame v\u00e4lja iga tilka. Vladimir Sitnikov\" src=\"\/wp-content\/uploads\/2020\/05\/6df83a2f3736568668cf9d74de5d9758.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Liigume praktikasse. N\u00e4eb v\u00e4lja nagu t\u00fc\u00fcpiline rakendus. See v\u00f5ib olla Java jne. <\/p>\n<p><\/p>\n<p>Me l\u00f5ime statement'i. K\u00e4ivitasime k\u00e4su. L\u00f5ime close. Kus on viga? Mis on probleem? Probleeme ei ole. Nii on kirjutatud k\u00f5igis raamatutes. Nii tuleb kirjutada. Kui tahate maksimaalset j\u00f5udlust, kirjutage nii. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"PostgreSQL ja JDBC pigistame v\u00e4lja iga tilka. Vladimir Sitnikov\" src=\"\/wp-content\/uploads\/2020\/05\/6923293946dec45b3fd508235728ab95.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Aga praktika n\u00e4itas, et see ei t\u00f6\u00f6ta. Miks? Sest meil on meetod \"close\". Ja kui me nii teeme, siis andmebaasi vaatenurgast on see nagu suitsetaja t\u00f6\u00f6 andmebaasiga. Me \u00fctlesime \"PARSE EXECUTE DEALLOCATE\".<\/p>\n<p><\/p>\n<p>Miks need liigsed statementide loomised ja eksportimine? Need ei ole kellelegi vajalikud. Aga tavaliselt on PreparedStatement'i puhul nii, et kui me need kinni paneme, siis nad sulgevad k\u00f5ik andmebaasis. See ei ole see, mida me soovime. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"PostgreSQL ja JDBC pigistame v\u00e4lja iga tilka. Vladimir Sitnikov\" src=\"\/wp-content\/uploads\/2020\/05\/5a357a209e414024c437d042f600f251.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Me tahame, nagu terved inimesed, andmebaasiga t\u00f6\u00f6tada. Otsustame \u00fche korra valmistada meie statement'i ja siis k\u00e4ivitame selle mitu korda. Tegelikult on palju kordi \u2013 see on \u00fcks kord kogu rakenduse elu jooksul parsimiseks. Ja kasutame erinevates REST'ides \u00fchte ja sama statement'i id-d. See on meie eesm\u00e4rk. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"PostgreSQL ja JDBC pigistame v\u00e4lja iga tilka. Vladimir Sitnikov\" src=\"\/wp-content\/uploads\/2020\/05\/ac4aed702a624ad9f9addc4362daf760.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Kuidas me sellele eesm\u00e4rgile j\u00f5uame? <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"PostgreSQL ja JDBC pigistame v\u00e4lja iga tilka. Vladimir Sitnikov\" src=\"\/wp-content\/uploads\/2020\/05\/0f101d890d1a2af8e99f8a3a8a06fd5a.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>V\u00e4ga lihtne - statements ei pea sulgema. Kirjutame nii: \"prepare\" \"execute\". <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"PostgreSQL ja JDBC pigistame v\u00e4lja iga tilka. Vladimir Sitnikov\" src=\"\/wp-content\/uploads\/2020\/05\/0b3fd8fd4f5861d4a76cad5a8421ddad.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"PostgreSQL ja JDBC pigistame v\u00e4lja iga tilka. Vladimir Sitnikov\" src=\"\/wp-content\/uploads\/2020\/05\/724646bfc55b5e2b611b1584ca8ba6aa.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Kui me midagi sellist k\u00e4ivitame, on selge, et kusagil mingi asi \u00fclet\u00e4idab. Kui ei ole selge, siis saame m\u00f5\u00f5ta. V\u00f5tame ja kirjutame benchmark'i, kus on lihtsalt selline meetod. Loome statement'i. K\u00e4ivitame mingis versioonis draiverist ja saame, et see kukub \u00fcsna kiiresti kokku m\u00e4lukaotusega, mis meil tekib. <\/p>\n<p><\/p>\n<p>Selge, et sellised vead on kergesti parandatavad. Ma ei hakka neist r\u00e4\u00e4kima. Kuid ma \u00fctlen, et uues versioonis t\u00f6\u00f6tab see palju kiiremini. Meetod on m\u00f5ttetu, kuid siiski. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"PostgreSQL ja JDBC pigistame v\u00e4lja iga tilka. Vladimir Sitnikov\" src=\"\/wp-content\/uploads\/2020\/05\/b232a6205e708c70f52be0024bbe9980.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Kuidas \u00f5igesti t\u00f6\u00f6tada? Mida me selleks peame tegema?<\/p>\n<p><\/p>\n<p>Tegelikult sulgevad rakendused alati statements'id. K\u00f5ikides raamatutes kirjutatakse, et peate need sulgema, vastasel juhul lekib m\u00e4lu. <\/p>\n<p><\/p>\n<p>Ja PostgreSQL ei oska p\u00e4ringuid vahem\u00e4lus hoida. Iga seanss peab oma jaoks selle vahem\u00e4lu looma. <\/p>\n<p><\/p>\n<p>Ja aega parsimisele me samuti ei taha kulutada. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"PostgreSQL ja JDBC pigistame v\u00e4lja iga tilka. Vladimir Sitnikov\" src=\"\/wp-content\/uploads\/2020\/05\/85b9574938aa6e6bf59c956e3728bdc3.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Ja nagu tavaliselt, on meil kaks varianti. <\/p>\n<p><\/p>\n<p>Esimene variant on, et v\u00f5tame ja \u00fctleme, et laseme k\u00f5ik PgSQL-i m\u00e4hkida. Seal on vahem\u00e4lu. See k\u00f5ik salvestatakse. Tulemus on imeline. Oleme sellist asja vaadanud. Meil on 100500 p\u00e4ringut. See ei toimi. Me ei ole n\u00f5us \u2013 k\u00e4sitsi muundama p\u00e4ringud protseduurideks. Ei-ei. <\/p>\n<p><\/p>\n<p>Meil on teine variant \u2013 v\u00f5tta ja ise teha. Avame l\u00e4htekoodid, alustame t\u00f6\u00f6d. T\u00f6\u00f6tame ja t\u00f6\u00f6tame. Selgub, et seda on mitte nii keeruline teha. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"PostgreSQL ja JDBC pigistame v\u00e4lja iga tilka. Vladimir Sitnikov\" src=\"\/wp-content\/uploads\/2020\/05\/501620b014800406167d20668baef709.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p><noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/pgjdbc\/pgjdbc\/pull\/319\">https:\/\/github.com\/pgjdbc\/pgjdbc\/pull\/319<\/a><\/noindex><\/p>\n<p><\/p>\n<p>See ilmus augustis 2015. Praegu on juba kaasaegsem versioon. Ja k\u00f5ik on suurep\u00e4rane. See t\u00f6\u00f6tab nii h\u00e4sti, et me ei muuda rakenduses midagi. Ja me oleme isegi l\u00f5petanud m\u00f5tlemise PgSQL-i suunas, st see oli piisav, et k\u00f5ik k\u00f5rvalkulud v\u00e4hendada praktiliselt nullini. <\/p>\n<p><\/p>\n<p>Seega Server-prepared statements aktiveeritakse 5. t\u00e4itmisel, et mitte raisata m\u00e4lu andmebaasis iga \u00fchekordse p\u00e4ringu jaoks. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"PostgreSQL ja JDBC pigistame v\u00e4lja iga tilka. Vladimir Sitnikov\" src=\"\/wp-content\/uploads\/2020\/05\/8ee95e71f92187941989ad0c18ece0c0.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>V\u00f5ib k\u00fcsida \u2013 kus arvud? Mida te saate? Ja siin ma arvuteid ei anna, sest iga p\u00e4ringu jaoks on need omad.<\/p>\n<p><\/p>\n<p>Meie p\u00e4ringud olid sellised, et OLTP-p\u00e4ringutes kulutasime umbes 20 millisekundit parsimiseks. Seal oli 0,5 millisekundit t\u00e4itmiseks, 20 millisekundit parsimiseks. P\u00e4ring \u2013 10 KiB teksti, 170 reavaadet. See on OLTP p\u00e4ring. See k\u00fcsib 1, 5, 10 rida, m\u00f5nikord rohkem. <\/p>\n<p><\/p>\n<p>Aga me ei tahtnud \u00fcldse kulutada 20 millisekundit. Me viisime selle nulli. K\u00f5ik on suurep\u00e4rane. <\/p>\n<p><\/p>\n<p>Mida te siit kaasa v\u00f5tate? Kui teil on Java, siis v\u00f5tate kaasaegse draiveri versiooni ja olete r\u00f5\u00f5msad. <\/p>\n<p><\/p>\n<p>Kui teil on m\u00f5ni muu keel, siis m\u00f5elge \u2013 v\u00f5ib-olla vajate ka seda? Sest l\u00f5ppkeele vaatepunktist, n\u00e4iteks kui PL 8 v\u00f5i teil on LibPQ, siis ei ole teile ilmselge, et te raiskate aega mitte t\u00e4itmiseks, vaid parsimiseks ja see tasub \u00fcle vaadata. Kuidas? K\u00f5ik tasuta. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"PostgreSQL ja JDBC pigistame v\u00e4lja iga tilka. Vladimir Sitnikov\" src=\"\/wp-content\/uploads\/2020\/05\/fda6b1c1b126cb85c970e42335e1dc24.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>V.a see, et on vigu, m\u00f5ned spetsiifikat. Ja neist me just praegu r\u00e4\u00e4gime. Suur osa tuleb t\u00f6\u00f6stuslikust arheoloogiast, sellest, mida oleme leidnud, millele oleme sattunud. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"PostgreSQL ja JDBC pigistame v\u00e4lja iga tilka. Vladimir Sitnikov\" src=\"\/wp-content\/uploads\/2020\/05\/9a3b383f83c5e227cd02952c5825b64f.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Kui p\u00e4ring genereeritakse d\u00fcnaamiliselt. Sedasi juhtub. Keegi liidab stringid, tulemuseks saab SQL-p\u00e4ring.<\/p>\n<p><\/p>\n<p>Miks see halb on? See on halb, sest iga kord saame l\u00f5puks erineva stringi.<\/p>\n<p><\/p>\n<p>Ja selle erineva reaga peab hashCode uuesti arvutama. See on t\u00f5epoolest CPU \u00fclesanne \u2013 leida pikka p\u00e4ringuteksti isegi olemasolevas hash' \u00fcheselt ei ole nii lihtne. Seet\u00f5ttu on lihtne j\u00e4reldus \u2013 \u00e4rge genereerige p\u00e4ringuid. Hoidke need mingis \u00fches muutujas. Ja r\u00f5\u00f5mustage.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"PostgreSQL ja JDBC pigistame v\u00e4lja iga tilka. Vladimir Sitnikov\" src=\"\/wp-content\/uploads\/2020\/05\/bcd4f729204cecdb572a98f357bcc33f.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>J\u00e4rgmine probleem. Andmet\u00fc\u00fcbid on olulised. On olemas ORM-id, mis \u00fctlevad, et pole vahet, milline NULL, olgu see mingi. Kui on Int, siis \u00fctleme setInt. Ja kui on NULL, siis olgu see alati VARCHAR. Ja mis vahet seal l\u00f5puks on, milline NULL? Andmebaasil on endal k\u00f5ik arusaadav. Ja selline pilt ei toimi. <\/p>\n<p><\/p>\n<p>Praktikas ei ole andmebaasilt sugugi k\u00f5ik \u00fchtemoodi. <strong>Kui olete esmakordselt \u00f6elnud, et see on teil number, ja teisel korral \u00f6elnud, et see on VARCHAR, siis ei saa Server-prepared statements'i uuesti kasutada. Sellisel juhul tuleb meie statement j\u00e4lle uuesti luua.<\/strong><\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"PostgreSQL ja JDBC pigistame v\u00e4lja iga tilka. Vladimir Sitnikov\" src=\"\/wp-content\/uploads\/2020\/05\/552d9c2e25cf9abbdfef12c98d027740.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Kui t\u00e4idate sama p\u00e4ringut, siis j\u00e4lgige, et andmet\u00fc\u00fcbid veergudes ei seguneks. Peab j\u00e4lgima NULL-i. See on sage viga, mis meil esines p\u00e4rast PreparedStatements'i kasutuselev\u00f5ttu.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"PostgreSQL ja JDBC pigistame v\u00e4lja iga tilka. Vladimir Sitnikov\" src=\"\/wp-content\/uploads\/2020\/05\/5d73c8f5dfa281c3bda962fc3e5edd84.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>H\u00e4sti, l\u00fclitasime sisse. V\u00f5ib-olla kasutasime draiverit. Ja j\u00f5udlus langes. K\u00f5ik muutus halvaks. <\/p>\n<p><\/p>\n<p>Kuidas see on v\u00f5imalik? Kas see on bug v\u00f5i funktsioon? Kahjuks ei \u00f5nnestunud m\u00f5ista \u2013 kas see on bug v\u00f5i funktsioon. Aga on t\u00e4iesti lihtne stsenaarium, kuidas seda probleemi paljundada. See ootamatult p\u00fc\u00fcdis meid kinni. Ja seisneb valimises, mis on praktiliselt ainult \u00fchest tabelist. Meil oli muidki selliseid p\u00e4ringuid. Need sisaldasid reeglina kahte-kolme tabelit, kuid siin on selline paljundamissenaarium. V\u00f5tke oma andmebaasist mis tahes versioon ja paljundage.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"PostgreSQL ja JDBC pigistame v\u00e4lja iga tilka. Vladimir Sitnikov\" src=\"\/wp-content\/uploads\/2020\/05\/fa0fdd037c2eaa31667d5a527bb71f9c.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p><noindex><a rel=\"nofollow\" href=\"https:\/\/gist.github.com\/vlsi\/df08cbef370b2e86a5c1\">https:\/\/gist.github.com\/vlsi\/df08cbef370b2e86a5c1<\/a><\/noindex><\/p>\n<p><\/p>\n<p>M\u00f5te on selles, et meil on kaks veergu, millest kummaski on indeks. \u00dches veerus on NULL-i v\u00e4\u00e4rtus miljon rida. Teises veerus on vaid 20 rida. Kui t\u00e4idame ilma sidumata muutujateta, siis k\u00f5ik t\u00f6\u00f6tab h\u00e4sti. <\/p>\n<p><\/p>\n<p>Kui hakkame t\u00e4itma sidustatud muutujatega, st t\u00e4idame m\u00e4rgi \"?\" v\u00f5i \"$1\" meie p\u00e4ringule, siis mida me l\u00f5puks saame?<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"PostgreSQL ja JDBC pigistame v\u00e4lja iga tilka. Vladimir Sitnikov\" src=\"\/wp-content\/uploads\/2020\/05\/e91c397796c7ddcbade3bc090719e9d1.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p><noindex><a rel=\"nofollow\" href=\"https:\/\/gist.github.com\/vlsi\/df08cbef370b2e86a5c1\">https:\/\/gist.github.com\/vlsi\/df08cbef370b2e86a5c1<\/a><\/noindex><\/p>\n<p><\/p>\n<p>Esimene t\u00e4itmine \u2013 nagu alati. Teine \u2013 natuke kiiremini. Midagi vahem\u00e4llu salvestus. Kolmas-neljanda viies. Siis plahvatab \u2013 ja just nii. Ja k\u00f5ige halvem on see, et see juhtub kuuendal t\u00e4itmisel. Kes teadis, et peab tegema just kuus t\u00e4itmist, et aru saada, milline seal reaalselt t\u00e4itmisplaan on?<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"PostgreSQL ja JDBC pigistame v\u00e4lja iga tilka. Vladimir Sitnikov\" src=\"\/wp-content\/uploads\/2020\/05\/893c955bc1e2e15a6986690e516f72a9.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Kes on s\u00fc\u00fcdi? Mis juhtus? Andmebaas sisaldab optsioonide optimeerimist. Ja see on nagu optimeeritud \u00fcldiseks olukorraks. Seet\u00f5ttu, alates mingist hetkest, liigub ta \u00fcldisele plaanile, mis, kahjuks, v\u00f5ib osutuda teistsuguseks. Ta v\u00f5ib osutuda samaks v\u00f5i teistsuguseks. Seal on mingi k\u00fcnnisv\u00e4\u00e4rtus, mis toob kaasa sellise k\u00e4itumise. <\/p>\n<p><\/p>\n<p>Mida sellega teha? Siin on t\u00f5en\u00e4oliselt keerulisem midagi oletada. On lihtne lahendus, mida me kasutame. See on +0, OFFSET 0. Kindlasti teate selliseid lahendusi. Lihtsalt v\u00f5tame ja lisame p\u00e4ringusse \u201e+0\u201d ja k\u00f5ik on h\u00e4sti. N\u00e4itan hiljem. <\/p>\n<p><\/p>\n<p>Ja on veel variant \u2013 vaadata hoolikamalt plaane. Arendaja peab mitte ainult p\u00e4ringut kirjutama, vaid ka 6 korda \u00fctlema \u201eexplain analyze\u201d. Kui 5, siis ei sobi. <\/p>\n<p><\/p>\n<p>Ja on veel kolmas variant \u2013 kirjutada pgsql-hackers-le kiri. Ma kirjutasin, t\u00f5si k\u00fcll, hetkel ei ole selge \u2013 kas see on viga v\u00f5i omadus.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"PostgreSQL ja JDBC pigistame v\u00e4lja iga tilka. Vladimir Sitnikov\" src=\"\/wp-content\/uploads\/2020\/05\/8dc8d3a78e0b794e1ceba20f6ca914ae.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p><noindex><a rel=\"nofollow\" href=\"https:\/\/gist.github.com\/vlsi\/df08cbef370b2e86a5c1\">https:\/\/gist.github.com\/vlsi\/df08cbef370b2e86a5c1<\/a><\/noindex><\/p>\n<p><\/p>\n<p>Kuni me m\u00f5tleme \u2013 kas see on viga v\u00f5i omadus, lahendame probleemid. V\u00f5tame meie p\u00e4ringu ja lisame \u201e+0\u201d. K\u00f5ik on h\u00e4sti. Kaks m\u00e4rki ja isegi ei pea m\u00f5tlema, kuidas ja mis seal on. V\u00e4ga lihtne. Me lihtsalt k\u00e4skisime andmebaasil mitte kasutada indeksi selle veeru jaoks. Meil ei ole indeksi veert \u201e+0\u201d ja k\u00f5ik, andmebaas ei kasuta indeksit, k\u00f5ik on h\u00e4sti. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"PostgreSQL ja JDBC pigistame v\u00e4lja iga tilka. Vladimir Sitnikov\" src=\"\/wp-content\/uploads\/2020\/05\/5261d80d084786a15b9764f6367014cd.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Siin on reegel 6 explain'ist. Hetkel k\u00e4esolevates versioonides tuleb teha 6 korda, kui teil on seotud muutujad. Kui teil ei ole seotud muutujaid, siis teeme nii. Ja meil l\u00f5puks t\u00e4pselt see p\u00e4ring kukub. Asi pole keeruline.<\/p>\n<p><\/p>\n<p>Tundub, kui kaua saab? Siin on viga, seal on viga. Tegelikult on viga igal pool. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"PostgreSQL ja JDBC pigistame v\u00e4lja iga tilka. Vladimir Sitnikov\" src=\"\/wp-content\/uploads\/2020\/05\/674dc7e7b4624baa5c79eee9e1e89db0.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Vaatame veel. N\u00e4iteks, meil on kaks skeemi. Skeem A tabeliga \u042b ja skeem B sama tabeliga \u042b. P\u00e4ring \u2013 valida andmed tabelist. Mis meil sellega on? Meil on viga. Meil on k\u00f5ik eelnevalt loetletud. Reegel on selline \u2013 viga igal pool, meil on k\u00f5ik eelnevalt loetletud.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"PostgreSQL ja JDBC pigistame v\u00e4lja iga tilka. Vladimir Sitnikov\" src=\"\/wp-content\/uploads\/2020\/05\/dd6f544bb9e930c39e36523c9afe6003.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>N\u00fc\u00fcd k\u00fcsimus: \u201eMiks?\u201d. Tundub, et on dokumentatsioon, et kui meil on skeem, siis on muutuja \u201esearch_path\u201d, mis \u00fctleb, kus peab otsima tabelit. Tundub, et muutuja on olemas.<\/p>\n<p><\/p>\n<p>Mis on probleem? Probleem on selles, et serveri valmistatud avaldused ei kahtle, et search_pathi v\u00f5ib keegi muuta. See v\u00e4\u00e4rtus j\u00e4\u00e4b andmebaasi jaoks nagu konstantseks. Ja m\u00f5ned osad ei pruugi haarata uusi v\u00e4\u00e4rtusi. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"PostgreSQL ja JDBC pigistame v\u00e4lja iga tilka. Vladimir Sitnikov\" src=\"\/wp-content\/uploads\/2020\/05\/f738301606d84d72bfa7cc5b568c0df8.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Loomulikult s\u00f5ltub see versioonist, millega te testite. See s\u00f5ltub ka sellest, kui ulatuslikud teie tabelid on. Versioon 9.1 k\u00e4ivitab lihtsalt vanad p\u00e4ringud. Uuemad versioonid v\u00f5ivad aga avastada petu ja \u00f6elda, et teil on viga.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"PostgreSQL ja JDBC pigistame v\u00e4lja iga tilka. Vladimir Sitnikov\" src=\"\/wp-content\/uploads\/2020\/05\/4761cd92835b94acbf9d6c9d21817316.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p><noindex><a rel=\"nofollow\" href=\"https:\/\/www.postgresql.org\/message-id\/CAB=Je-GQOW7kU9Hn3AqP1vhaZg_wE9Lz6F4jSp-7cm9_M6DyVA@mail.gmail.com\">Seadke search_path + serveri ettevalmistatud laused =<br \/>\nvahem\u00e4lu plaan ei tohi muuta tulemuste t\u00fc\u00fcpi<\/a><\/noindex><\/p>\n<p><\/p>\n<p>Kuidas seda parandada? Lihtne retsept \u2013 \u00e4rge tehke nii. \u00c4rge muutke search_path'i rakenduse t\u00f6\u00f6 k\u00e4igus. Kui muudate, siis on parem luua uus \u00fchendus.<\/p>\n<p><\/p>\n<p>Saame arutada, st avada, arutada ja kirjutada juurde. V\u00f5ib-olla suudame veenda andmebaasi arendajaid, et juhul, kui keegi muudab v\u00e4\u00e4rtust, peaks andmebaas sellest kliendile teatama: \u201eVaadake, teie v\u00e4\u00e4rtus on siin uuendatud. Kas peaksite statements'id l\u00e4htestama, uuesti looma?\u201d. Praegu k\u00e4itub andmebaas salaja ja ei teata mingil moel, et kuskil sees on statements'id muutunud. <\/p>\n<p><\/p>\n<p>Ja ma r\u00f5hutan taas \u2013 see pole Java puhul t\u00fc\u00fcpiline. N\u00e4eme seda sama ka PL\/pgSQL'is s\u00f5na-s\u00f5nalt. Seal see ka kordub.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"PostgreSQL ja JDBC pigistame v\u00e4lja iga tilka. Vladimir Sitnikov\" src=\"\/wp-content\/uploads\/2020\/05\/a4e7b201d0c0aa4a0092d2b6ff152df7.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Proovime veel andmeid valida. Valime, valime. Meil on tabel, kus on miljon rida. Iga rida \u00fcks kilobait. Umbes gigabait andmeid. Ja meil on Java masina t\u00f6\u00f6tav m\u00e4lu 128 megabaiti. <\/p>\n<p><\/p>\n<p>Kasutame nagu k\u00f5ikides raamatutes soovitatakse voogedastust. St avame resultSet ja loeme sealt andmeid tasapisi. Kas see t\u00f6\u00f6tab? Kas see ei kuku m\u00e4lu t\u00f5ttu? Kas see loeb natuke? Usume andmebaasi, usume Postgressesse. Ei usu. Kukume OutOfMemory? Kes on kukkunud OutOfMemory? Ja kes suutis p\u00e4rast seda parandada? Keegi suutis parandada. <\/p>\n<p><\/p>\n<p>Kui teil on miljon rida, siis ei saa lihtsalt nii valida. Peab kindlasti olema OFFSET\/LIMIT. Kes on sellise variandi poolt? Ja kes on variandi poolt, et tuleb autoCommit'iga m\u00e4ngida? <\/p>\n<p><\/p>\n<p>Siin, nagu tavaliselt, osutub k\u00f5ige ootamatum variant \u00f5igeks. Ja kui te \u00e4kitselt l\u00fclitate autoCommit'i v\u00e4lja, siis see aitab. Miks nii? Teadusele see ei ole teada. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"PostgreSQL ja JDBC pigistame v\u00e4lja iga tilka. Vladimir Sitnikov\" src=\"\/wp-content\/uploads\/2020\/05\/2e5d9d2a8450a9069155de86a8ec387a.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Aga vaikimisi valivad k\u00f5ik kliendid, kes \u00fchenduvad Postgres andmebaasiga, andmeid tervikuna. PgJDBC selle osas pole erand, valib k\u00f5ik read.<\/p>\n<p><\/p>\n<p>On variatsioon FetchSize'il, st saate eraldi statements'i tasandil \u00f6elda, et siit palun valige andmeid 10, 50. Kuid see ei t\u00f6\u00f6ta, kuni te ei l\u00fclita autoCommit'i v\u00e4lja. L\u00fclitasite autoCommit'i v\u00e4lja \u2013 hakkab t\u00f6\u00f6le. <\/p>\n<p><\/p>\n<p>Koodi l\u00e4bimine ja igal pool setFetchSize seadmine on ebamugav. Seet\u00f5ttu tegime sellise seadistuse, mis m\u00e4\u00e4rab vaikimisi v\u00e4\u00e4rtuse kogu \u00fchenduse jaoks.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"PostgreSQL ja JDBC pigistame v\u00e4lja iga tilka. Vladimir Sitnikov\" src=\"\/wp-content\/uploads\/2020\/05\/c9ac8e483dc6bfdbbc300972ee1ab1e0.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Nii et me seda \u00fctlesime. Seadisime parameetri. Ja mis me n\u00fc\u00fcd saime? Kui valime v\u00e4ikese, n\u00e4iteks 10 rida, siis on meie kulud \u00fcsna suured. Seet\u00f5ttu peaksime selle v\u00e4\u00e4rtuse seadma umbes sajale. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"PostgreSQL ja JDBC pigistame v\u00e4lja iga tilka. Vladimir Sitnikov\" src=\"\/wp-content\/uploads\/2020\/05\/073e7a4af63688396eefe332ba8261d6.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Ideaalis v\u00f5iksime muidugi \u00f5ppida piirama ka baitides, aga retsept on selline: seab defaultRowFetchSize \u00fcle saja ja oleme rahul. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"PostgreSQL ja JDBC pigistame v\u00e4lja iga tilka. Vladimir Sitnikov\" src=\"\/wp-content\/uploads\/2020\/05\/e3078faf2078fcaec10d6d99872a9990.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Liigume andmete sisestamise juurde. Sisestamine on lihtsam, seal on erinevaid variante. N\u00e4iteks, INSERT, VALUES. See on hea variant. V\u00f5ime r\u00e4\u00e4kida \"INSERT SELECT\". Praktikas on need \u00fcks ja sama. Erinevust j\u00f5udluses ei ole. <\/p>\n<p><\/p>\n<p>Raamatud \u00fctlevad, et tuleb t\u00e4ita Batch statement, raamatud \u00fctlevad, et v\u00f5ib t\u00e4ita keerulisemaid k\u00e4ske mitme sulgudega. Ja Postgres'is on suurep\u00e4rane funktsioon - v\u00f5ib teha COPY, st teha seda kiiremini. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"PostgreSQL ja JDBC pigistame v\u00e4lja iga tilka. Vladimir Sitnikov\" src=\"\/wp-content\/uploads\/2020\/05\/4d281c9515bdf8de7fbf1e9922d192d0.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Kui m\u00f5\u00f5ta, v\u00f5ib teha uuesti mitmeid huvitavaid avastusi. Kuidas me tahame, et see t\u00f6\u00f6tab? Tahame mitte parsida ja mitte t\u00e4iendavaid k\u00e4ske t\u00e4ita. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"PostgreSQL ja JDBC pigistame v\u00e4lja iga tilka. Vladimir Sitnikov\" src=\"\/wp-content\/uploads\/2020\/05\/7b2e4343c51dab3ddb6919bf0f117c4d.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Praktikas ei lase TCP meil nii teha. Kui klient on h\u00f5ivatud p\u00e4ringu saatmisega, siis andmebaas proovib meile vastuseid saata, aga p\u00e4ringuid ei loeta. L\u00f5puks ootab klient andmebaasi, kuni see p\u00e4ringu loeb, samal ajal kui andmebaas ootab klienti, kuni see vastuse loeb. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"PostgreSQL ja JDBC pigistame v\u00e4lja iga tilka. Vladimir Sitnikov\" src=\"\/wp-content\/uploads\/2020\/05\/17a062c30ddd83cb890775ec1722044f.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Seet\u00f5ttu peab klient perioodiliselt saatma s\u00fcnkroniseerimise paketi. \u00dcksikud v\u00f5rgu suhtlused, aeglane ajakadu.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"PostgreSQL ja JDBC pigistame v\u00e4lja iga tilka. Vladimir Sitnikov\" src=\"\/wp-content\/uploads\/2020\/05\/ae7a4f32e2949c1d0550da051937de02.jpg\" style=\"display:block;margin: 0 auto;\" \/>Ja mida rohkem me neid lisame, seda halvemaks l\u00e4heb. Draiver on \u00fcsna pessimistlik ja lisab neid \u00fcsna sageli, umbes iga 200 rea j\u00e4rel, s\u00f5ltuvalt ridade suurusest jms. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"PostgreSQL ja JDBC pigistame v\u00e4lja iga tilka. Vladimir Sitnikov\" src=\"\/wp-content\/uploads\/2020\/05\/82b1d597986633a8c4b7952517ca6477.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p><noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/pgjdbc\/pgjdbc\/pull\/380\">https:\/\/github.com\/pgjdbc\/pgjdbc\/pull\/380<\/a><\/noindex><\/p>\n<p><\/p>\n<p>Juhtub, et parandad \u00fchte rida ja k\u00f5ik kiireneb 10 korda. Nii juhtub. Miks? Nagu tavaliselt, mingi konstandi oli seal juba kasutatud. Ja v\u00e4\u00e4rtus \u201e128\u201d t\u00e4hendas - mitte kasutada batchingut.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"PostgreSQL ja JDBC pigistame v\u00e4lja iga tilka. Vladimir Sitnikov\" src=\"\/wp-content\/uploads\/2020\/05\/7b6bcd95591b36441037b4c4631d2ad0.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p><noindex><a rel=\"nofollow\" href=\"http:\/\/openjdk.java.net\/projects\/code-tools\/jmh\/\">Java microbenchmark harness<\/a><\/noindex><\/p>\n<p><\/p>\n<p>Hea, et see ei sattunud ametlikku versioonisse. Leidsime selle enne, kui hakkasime v\u00e4lja andma v\u00e4ljaannet. K\u00f5ik v\u00e4\u00e4rtused, mida ma nimetan, p\u00f5hinevad kaasaegsetel versioonidel. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"PostgreSQL ja JDBC pigistame v\u00e4lja iga tilka. Vladimir Sitnikov\" src=\"\/wp-content\/uploads\/2020\/05\/28c82d9e11f6bdaf3cf62b49fc074d68.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>M\u00f5\u00f5game. Me m\u00f5\u00f5dame lihtsat InsertBatch'i. Me m\u00f5\u00f5dame mitmekordset InsertBatch'i, st sama asi, kuid palju values. Kaval k\u00e4ik. Mitte k\u00f5ik ei oska nii teha, aga see on lihtne k\u00e4ik, palju lihtsam kui COPY.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"PostgreSQL ja JDBC pigistame v\u00e4lja iga tilka. Vladimir Sitnikov\" src=\"\/wp-content\/uploads\/2020\/05\/72f7cf6c3b9d9175d3e5a6d5410fe209.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Saab teha COPY.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"PostgreSQL ja JDBC pigistame v\u00e4lja iga tilka. Vladimir Sitnikov\" src=\"\/wp-content\/uploads\/2020\/05\/2b0d8bbcc50f1293c9a8a1eb8eb70d2e.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Ja saab seda teha struktuurides. Deklareeri kasutaja vaikimisi t\u00fc\u00fcp, edastades massiivi ja INSERT otse tabelisse. <\/p>\n<p><\/p>\n<p>Kui avate lingi: pgjdbc\/ubenchmsrk\/InsertBatch.java, siis see kood on GitHubis. Saate vaadata t\u00e4pselt, milliseks p\u00e4ringud seal genereeritakse. See ei ole olulised.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"PostgreSQL ja JDBC pigistame v\u00e4lja iga tilka. Vladimir Sitnikov\" src=\"\/wp-content\/uploads\/2020\/05\/28dede211fe401286685ca62081453de.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Me k\u00e4ivitasime selle. Ja esimene asi, mille me m\u00f5istsime, oli see, et batchi mittekasutamine on lihtsalt v\u00e4listatud. K\u00f5ik batchimise variandid on nullid, st t\u00e4itmise aeg on praktiliselt null v\u00f5rreldes \u00fchekordse t\u00e4itmisega. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"PostgreSQL ja JDBC pigistame v\u00e4lja iga tilka. Vladimir Sitnikov\" src=\"\/wp-content\/uploads\/2020\/05\/4ea68f712bbdeadd35f5baa4ddaeff33.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Me sisestame andmed. Seal on v\u00e4ga lihtne tabel. Kolm veergu. Ja mida me siin n\u00e4eme? Me n\u00e4eme, et k\u00f5ik need kolm varianti on umbes v\u00f5rreldavad. Ja COPY on loomulikult parem.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"PostgreSQL ja JDBC pigistame v\u00e4lja iga tilka. Vladimir Sitnikov\" src=\"\/wp-content\/uploads\/2020\/05\/2686f1d7eea347a839ac23aef2a27e53.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>See, kui me t\u00fckikaupa sisestame. Kui me r\u00e4\u00e4kisime, et \u00fcks v\u00e4\u00e4rtus VALUES, kaks v\u00e4\u00e4rtust VALUES, kolm v\u00e4\u00e4rtust VALUES v\u00f5i kui me neid 10 komaga nimetasime. See peaks olema n\u00fc\u00fcd horisontaalsel tasandil. 1, 2, 4, 128. On n\u00e4ha, et Batch Insert, mis on siniseks joonistatud, muudab asja kergemaks. St kui sisestate \u00fckshaaval v\u00f5i isegi nelja kaupa, siis see aitab kahel korral paremini, lihtsalt seet\u00f5ttu, et me panime VALUESisse veidi rohkem. V\u00e4hem EXECUTE operatsioone.<\/p>\n<p><\/p>\n<p>Kopeerimise kasutamine v\u00e4ikeste mahtude korral on \u00e4\u00e4rmiselt v\u00e4helootustandev. Ma ei joonistanud isegi kahe esimesega. Need l\u00e4hevad taevasse, st need rohelised numbrid jaoks COPY.<\/p>\n<p><\/p>\n<p>COPY-d tuleks kasutada, kui teie andmemaht on v\u00e4hemalt \u00fcle saja rea. \u00dchenduse avamise kulud on suured. Ja, ausalt \u00f6eldes, ma ei ole selle poolega s\u00fcvenenud. Batch'i optimeerisin, COPY-d mitte. <\/p>\n<p><\/p>\n<p>Mida me edasi teeme? Me m\u00f5\u00f5dame. Saame aru, et peame kasutama kas struktuure v\u00f5i nutikat batching'u, mis liidab mitu v\u00e4\u00e4rtust. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"PostgreSQL ja JDBC pigistame v\u00e4lja iga tilka. Vladimir Sitnikov\" src=\"\/wp-content\/uploads\/2020\/05\/e02fa2574e2d1b678382db15064610d3.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Mida tuleb t\u00e4nasest ettekandest v\u00e4lja tuua?<\/p>\n<p><\/p>\n<ul>\n<li>PreparedStatement \u2013 see on meie k\u00f5ik. See toob v\u00e4ga palju kaasa j\u00f5udlusele. See toob suure alusikka. <\/li>\n<li>Ja tuleb teha EXPLAIN ANALYZE 6 korda.<\/li>\n<li>Ja tuleb lahjendada OFFSET 0 ning trikkidega nagu +0, et korvata veel j\u00e4\u00e4nud protsent meie probleemsetest p\u00e4ringutest.<\/li>\n<\/ul>\n<p>Allikas: <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/post\/499794\/\">habr.com<\/a> <\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>\u041f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u044e \u043e\u0437\u043d\u0430\u043a\u043e\u043c\u0438\u0442\u044c\u0441\u044f \u0441 \u0440\u0430\u0441\u0448\u0438\u0444\u0440\u043e\u0432\u043a\u043e\u0439 \u0434\u043e\u043a\u043b\u0430\u0434\u0430 \u043d\u0430\u0447\u0430\u043b\u0430 2016 \u0433\u043e\u0434\u0430 \u0412\u043b\u0430\u0434\u0438\u043c\u0438\u0440\u0430 \u0421\u0438\u0442\u043d\u0438\u043a\u043e\u0432\u0430 &quot;PostgreSQL \u0438 JDBC \u0432\u044b\u0436\u0438\u043c\u0430\u0435\u043c \u0432\u0441\u0435 \u0441\u043e\u043a\u0438&quot; \u0414\u043e\u0431\u0440\u044b\u0439 \u0434\u0435\u043d\u044c! \u041c\u0435\u043d\u044f \u0437\u043e\u0432\u0443\u0442 \u0412\u043b\u0430\u0434\u0438\u043c\u0438\u0440 \u0421\u0438\u0442\u043d\u0438\u043a\u043e\u0432. \u042f \u0440\u0430\u0431\u043e\u0442\u0430\u044e 10 \u043b\u0435\u0442 \u0432 \u043a\u043e\u043c\u043f\u0430\u043d\u0438\u0438 NetCracker. \u0418 \u0432 \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u043c \u044f \u0437\u0430\u043d\u0438\u043c\u0430\u044e\u0441\u044c \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c\u044e. \u0412\u0441\u0435, \u0447\u0442\u043e \u0441\u0432\u044f\u0437\u0430\u043d\u043e \u0441 Java, \u0432\u0441\u0435, \u0447\u0442\u043e \u0441\u0432\u044f\u0437\u0430\u043d\u043e \u0441 SQL \u2013 \u044d\u0442\u043e \u0442\u043e, \u0447\u0442\u043e \u044f \u043b\u044e\u0431\u043b\u044e. \u0418 \u0441\u0435\u0433\u043e\u0434\u043d\u044f \u044f \u0440\u0430\u0441\u0441\u043a\u0430\u0436\u0443 [&hellip;]<\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"author":1,"featured_media":79894,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[688],"tags":[],"class_list":["post-79893","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=\"\u041f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u044e \u043e\u0437\u043d\u0430\u043a\u043e\u043c\u0438\u0442\u044c\u0441\u044f \u0441 \u0440\u0430\u0441\u0448\u0438\u0444\u0440\u043e\u0432\u043a\u043e\u0439 \u0434\u043e\u043a\u043b\u0430\u0434\u0430 \u043d\u0430\u0447\u0430\u043b\u0430 2016 \u0433\u043e\u0434\u0430 \u0412\u043b\u0430\u0434\u0438\u043c\u0438\u0440\u0430 \u0421\u0438\u0442\u043d\u0438\u043a\u043e\u0432\u0430 &quot;PostgreSQL \u0438 JDBC \u0432\u044b\u0436\u0438\u043c\u0430\u0435\u043c \u0432\u0441\u0435 \u0441\u043e\u043a\u0438&quot;\" \/>\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\/postgresql-i-jdbc-vyzhimaem-vse-soki-vladimir-sitnikov\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.1.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\udd47PostgreSQL \u0438 JDBC \u0432\u044b\u0436\u0438\u043c\u0430\u0435\u043c \u0432\u0441\u0435 \u0441\u043e\u043a\u0438. \u0412\u043b\u0430\u0434\u0438\u043c\u0438\u0440 \u0421\u0438\u0442\u043d\u0438\u043a\u043e\u0432 | ProHoster\" \/>\n\t\t<meta property=\"og:description\" content=\"\u041f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u044e \u043e\u0437\u043d\u0430\u043a\u043e\u043c\u0438\u0442\u044c\u0441\u044f \u0441 \u0440\u0430\u0441\u0448\u0438\u0444\u0440\u043e\u0432\u043a\u043e\u0439 \u0434\u043e\u043a\u043b\u0430\u0434\u0430 \u043d\u0430\u0447\u0430\u043b\u0430 2016 \u0433\u043e\u0434\u0430 \u0412\u043b\u0430\u0434\u0438\u043c\u0438\u0440\u0430 \u0421\u0438\u0442\u043d\u0438\u043a\u043e\u0432\u0430 &quot;PostgreSQL \u0438 JDBC \u0432\u044b\u0436\u0438\u043c\u0430\u0435\u043c \u0432\u0441\u0435 \u0441\u043e\u043a\u0438&quot;\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/et\/blog\/administrirovanie\/postgresql-i-jdbc-vyzhimaem-vse-soki-vladimir-sitnikov\" \/>\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-05-01T11:43:12+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2020-05-01T11:43:12+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\udd47PostgreSQL ja JDBC pigistame viimased mahlad v\u00e4lja. Vladimir Sitnikov | ProHoster","description":"Soovitan tutvuda Vladimir Sitnikovi 2016. aasta alguses peetud ettekande \"PostgreSQL ja JDBC pigistame v\u00e4lja iga tilka\" kokkuv\u00f5ttega","canonical_url":"https:\/\/prohoster.info\/et\/blog\/administrirovanie\/postgresql-i-jdbc-vyzhimaem-vse-soki-vladimir-sitnikov","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\udd47PostgreSQL \u0438 JDBC \u0432\u044b\u0436\u0438\u043c\u0430\u0435\u043c \u0432\u0441\u0435 \u0441\u043e\u043a\u0438. \u0412\u043b\u0430\u0434\u0438\u043c\u0438\u0440 \u0421\u0438\u0442\u043d\u0438\u043a\u043e\u0432 | ProHoster","og:description":"\u041f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u044e \u043e\u0437\u043d\u0430\u043a\u043e\u043c\u0438\u0442\u044c\u0441\u044f \u0441 \u0440\u0430\u0441\u0448\u0438\u0444\u0440\u043e\u0432\u043a\u043e\u0439 \u0434\u043e\u043a\u043b\u0430\u0434\u0430 \u043d\u0430\u0447\u0430\u043b\u0430 2016 \u0433\u043e\u0434\u0430 \u0412\u043b\u0430\u0434\u0438\u043c\u0438\u0440\u0430 \u0421\u0438\u0442\u043d\u0438\u043a\u043e\u0432\u0430 &quot;PostgreSQL \u0438 JDBC \u0432\u044b\u0436\u0438\u043c\u0430\u0435\u043c \u0432\u0441\u0435 \u0441\u043e\u043a\u0438&quot;","og:url":"https:\/\/prohoster.info\/et\/blog\/administrirovanie\/postgresql-i-jdbc-vyzhimaem-vse-soki-vladimir-sitnikov","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-05-01T11:43:12+00:00","article:modified_time":"2020-05-01T11:43:12+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"79893","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 16:29:39","updated":"2022-10-10 00:32:43","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\/79893","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=79893"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/et\/wp-json\/wp\/v2\/posts\/79893\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/et\/wp-json\/wp\/v2\/media\/79894"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/et\/wp-json\/wp\/v2\/media?parent=79893"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/et\/wp-json\/wp\/v2\/categories?post=79893"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/et\/wp-json\/wp\/v2\/tags?post=79893"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}