PostgreSQL ja JDBC pigistame vÀlja iga tilka. Vladimir Sitnikov

Soovitan tutvuda Vladimir Sitnikovi 2016. aasta alguses peetud ettekande "PostgreSQL ja JDBC pigistame vÀlja iga tilka" kokkuvÔttega

PostgreSQL ja JDBC pigistame vÀlja iga tilka. Vladimir Sitnikov

PostgreSQL ja JDBC pigistame vÀlja iga tilka. Vladimir Sitnikov

Tere pĂ€eva! Minu nimi on Vladimir Sitnikov. Töösklen ettevĂ”ttes NetCracker juba 10 aastat. Ja peamiselt tegelen tootlikkuse kĂŒsimustega. KĂ”ik, mis on seotud Java ja SQL-iga, on see, mida ma armastan.

Ja tÀna rÀÀgin teile sellest, millega me ettevÔttes silmitsi seisime, kui hakkasime PostgreSQL kasutama andmebaasiserverina. Peamiselt töötame Java'ga. Kuid see, millest ma tÀna rÀÀgin, ei seondu vaid Java'ga. Kogemus on nÀidanud, et sama juhtub ka teistes keeltes.

PostgreSQL ja JDBC pigistame vÀlja iga tilka. Vladimir Sitnikov

RÀÀgime jÀrgmistest asjadest:

  • andmete valimisest.
  • Andmete salvestamisest.
  • Ning tootlikkusest.
  • Ja ka peidetud kaevandustest, mis seal on.

PostgreSQL ja JDBC pigistame vÀlja iga tilka. Vladimir Sitnikov

Alustame lihtsast kĂŒsimusest. Valime tabelist ĂŒhe rea primaarvĂ”tme alusel.

PostgreSQL ja JDBC pigistame vÀlja iga tilka. Vladimir Sitnikov

Andmebaas asub samal hostil. Ja kogu see tegevus kestab 20 millisekundit.

PostgreSQL ja JDBC pigistame vÀlja iga tilka. Vladimir Sitnikov

Need 20 millisekundit on vÀga palju. Kui teil on 100 sellist pÀringut, siis kulutate aega sekundites, et neid pÀringuid töödeldada, st raiskate aega.

Me ei soovi seda teha ja vaatame, mida andmebaas meile selleks pakub. Andmebaas pakub meile kahte valikut pÀringute tÀitmiseks.

PostgreSQL ja JDBC pigistame vÀlja iga tilka. Vladimir Sitnikov

Esimene variant on lihtne pÀring. Miks see on hea? Sellega on see, et me vÔtame selle ja saadame, ja ei midagi enamat.

PostgreSQL ja JDBC pigistame vÀlja iga tilka. Vladimir Sitnikov

https://github.com/pgjdbc/pgjdbc/pull/478

Andmebaasil on veel ka tĂ€iustatud pĂ€ring, mis on keerulisem, kuid funktsionaalsem. VĂ”ib eraldi saata pĂ€ringu parsimiseks, tĂ€itmiseks, muutujate ĂŒhendamiseks jne.

Super tĂ€iustatud pĂ€ring – seda me ei kĂ€sitle praeguses ettekandes. VĂ”ib-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Ă€hima aasta jooksul vĂ”imalik. SeetĂ”ttu kirjutasime selle lihtsalt ĂŒles ja kĂ€ime peamisi inimesi pommitamas.

PostgreSQL ja JDBC pigistame vÀlja iga tilka. Vladimir Sitnikov

Aga see, mida me saame teha, on lihtne pÀring ja tÀiustatud pÀring.

Mis on iga lÀhenemise eripÀra?

Lihtsat pĂ€ringut on hea kasutada ĂŒhekordseks tĂ€itmiseks. TĂ€idetud ja unustatud. Probleem on selles, et see ei toeta binaarset andmevormingut, st mĂ”ned kĂ”rge jĂ”udlusega sĂŒsteemid ei sobi selleks.

PostgreSQL ja JDBC pigistame vÀlja iga tilka. Vladimir Sitnikov

Pikendatud pÀring - aitab sÀÀsta aega parsimisel. See on see, mida me tegime ja hakkasime kasutama. See on meid ÀÀrmiselt aidanud. Siin on mitte ainult sÀÀst parsimisel. On olemas ka andmete edastamise sÀÀst. Andmete edastamine binaarses formaadis on oluliselt efektiivsem.

PostgreSQL ja JDBC pigistame vÀlja iga tilka. Vladimir Sitnikov

Liigume praktikasse. NĂ€eb vĂ€lja nagu tĂŒĂŒpiline rakendus. See vĂ”ib olla Java jne.

Me lÔime statement'i. KÀivitasime kÀsu. LÔime close. Kus on viga? Mis on probleem? Probleeme ei ole. Nii on kirjutatud kÔigis raamatutes. Nii tuleb kirjutada. Kui tahate maksimaalset jÔudlust, kirjutage nii.

PostgreSQL ja JDBC pigistame vÀlja iga tilka. Vladimir Sitnikov

Aga praktika nĂ€itas, et see ei tööta. Miks? Sest meil on meetod "close". Ja kui me nii teeme, siis andmebaasi vaatenurgast on see nagu suitsetaja töö andmebaasiga. Me ĂŒtlesime "PARSE EXECUTE DEALLOCATE".

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Ôik andmebaasis. See ei ole see, mida me soovime.

PostgreSQL ja JDBC pigistame vÀlja iga tilka. Vladimir Sitnikov

Me tahame, nagu terved inimesed, andmebaasiga töötada. Otsustame ĂŒhe korra valmistada meie statement'i ja siis kĂ€ivitame selle mitu korda. Tegelikult on palju kordi – see on ĂŒks kord kogu rakenduse elu jooksul parsimiseks. Ja kasutame erinevates REST'ides ĂŒhte ja sama statement'i id-d. See on meie eesmĂ€rk.

PostgreSQL ja JDBC pigistame vÀlja iga tilka. Vladimir Sitnikov

Kuidas me sellele eesmÀrgile jÔuame?

PostgreSQL ja JDBC pigistame vÀlja iga tilka. Vladimir Sitnikov

VĂ€ga lihtne - statements ei pea sulgema. Kirjutame nii: "prepare" "execute".

PostgreSQL ja JDBC pigistame vÀlja iga tilka. Vladimir Sitnikov

PostgreSQL ja JDBC pigistame vÀlja iga tilka. Vladimir Sitnikov

Kui me midagi sellist kĂ€ivitame, on selge, et kusagil mingi asi ĂŒletĂ€idab. Kui ei ole selge, siis saame mÔÔta. VĂ”tame ja kirjutame benchmark'i, kus on lihtsalt selline meetod. Loome statement'i. KĂ€ivitame mingis versioonis draiverist ja saame, et see kukub ĂŒsna kiiresti kokku mĂ€lukaotusega, mis meil tekib.

Selge, et sellised vead on kergesti parandatavad. Ma ei hakka neist rÀÀkima. Kuid ma ĂŒtlen, et uues versioonis töötab see palju kiiremini. Meetod on mĂ”ttetu, kuid siiski.

PostgreSQL ja JDBC pigistame vÀlja iga tilka. Vladimir Sitnikov

Kuidas Ôigesti töötada? Mida me selleks peame tegema?

Tegelikult sulgevad rakendused alati statements'id. KÔikides raamatutes kirjutatakse, et peate need sulgema, vastasel juhul lekib mÀlu.

Ja PostgreSQL ei oska pÀringuid vahemÀlus hoida. Iga seanss peab oma jaoks selle vahemÀlu looma.

Ja aega parsimisele me samuti ei taha kulutada.

PostgreSQL ja JDBC pigistame vÀlja iga tilka. Vladimir Sitnikov

Ja nagu tavaliselt, on meil kaks varianti.

Esimene variant on, et vĂ”tame ja ĂŒtleme, et laseme kĂ”ik PgSQL-i mĂ€hkida. Seal on vahemĂ€lu. See kĂ”ik salvestatakse. Tulemus on imeline. Oleme sellist asja vaadanud. Meil on 100500 pĂ€ringut. See ei toimi. Me ei ole nĂ”us – kĂ€sitsi muundama pĂ€ringud protseduurideks. Ei-ei.

Meil on teine variant – vĂ”tta ja ise teha. Avame lĂ€htekoodid, alustame tööd. Töötame ja töötame. Selgub, et seda on mitte nii keeruline teha.

PostgreSQL ja JDBC pigistame vÀlja iga tilka. Vladimir Sitnikov

https://github.com/pgjdbc/pgjdbc/pull/319

See ilmus augustis 2015. Praegu on juba kaasaegsem versioon. Ja kÔik on suurepÀrane. See töötab nii hÀsti, et me ei muuda rakenduses midagi. Ja me oleme isegi lÔpetanud mÔtlemise PgSQL-i suunas, st see oli piisav, et kÔik kÔrvalkulud vÀhendada praktiliselt nullini.

Seega Server-prepared statements aktiveeritakse 5. tĂ€itmisel, et mitte raisata mĂ€lu andmebaasis iga ĂŒhekordse pĂ€ringu jaoks.

PostgreSQL ja JDBC pigistame vÀlja iga tilka. Vladimir Sitnikov

VĂ”ib kĂŒsida – kus arvud? Mida te saate? Ja siin ma arvuteid ei anna, sest iga pĂ€ringu jaoks on need omad.

Meie pĂ€ringud olid sellised, et OLTP-pĂ€ringutes kulutasime umbes 20 millisekundit parsimiseks. Seal oli 0,5 millisekundit tĂ€itmiseks, 20 millisekundit parsimiseks. PĂ€ring – 10 KiB teksti, 170 reavaadet. See on OLTP pĂ€ring. See kĂŒsib 1, 5, 10 rida, mĂ”nikord rohkem.

Aga me ei tahtnud ĂŒldse kulutada 20 millisekundit. Me viisime selle nulli. KĂ”ik on suurepĂ€rane.

Mida te siit kaasa vÔtate? Kui teil on Java, siis vÔtate kaasaegse draiveri versiooni ja olete rÔÔmsad.

Kui teil on mĂ”ni muu keel, siis mĂ”elge – vĂ”ib-olla vajate ka seda? Sest lĂ”ppkeele vaatepunktist, nĂ€iteks kui PL 8 vĂ”i teil on LibPQ, siis ei ole teile ilmselge, et te raiskate aega mitte tĂ€itmiseks, vaid parsimiseks ja see tasub ĂŒle vaadata. Kuidas? KĂ”ik tasuta.

PostgreSQL ja JDBC pigistame vÀlja iga tilka. Vladimir Sitnikov

V.a see, et on vigu, mÔned spetsiifikat. Ja neist me just praegu rÀÀgime. Suur osa tuleb tööstuslikust arheoloogiast, sellest, mida oleme leidnud, millele oleme sattunud.

PostgreSQL ja JDBC pigistame vÀlja iga tilka. Vladimir Sitnikov

Kui pĂ€ring genereeritakse dĂŒnaamiliselt. Sedasi juhtub. Keegi liidab stringid, tulemuseks saab SQL-pĂ€ring.

Miks see halb on? See on halb, sest iga kord saame lÔpuks erineva stringi.

Ja selle erineva reaga peab hashCode uuesti arvutama. See on tĂ”epoolest CPU ĂŒlesanne – leida pikka pĂ€ringuteksti isegi olemasolevas hash' ĂŒheselt ei ole nii lihtne. SeetĂ”ttu on lihtne jĂ€reldus – Ă€rge genereerige pĂ€ringuid. Hoidke need mingis ĂŒhes muutujas. Ja rÔÔmustage.

PostgreSQL ja JDBC pigistame vÀlja iga tilka. Vladimir Sitnikov

JĂ€rgmine probleem. AndmetĂŒĂŒbid on olulised. On olemas ORM-id, mis ĂŒtlevad, et pole vahet, milline NULL, olgu see mingi. Kui on Int, siis ĂŒtleme setInt. Ja kui on NULL, siis olgu see alati VARCHAR. Ja mis vahet seal lĂ”puks on, milline NULL? Andmebaasil on endal kĂ”ik arusaadav. Ja selline pilt ei toimi.

Praktikas ei ole andmebaasilt sugugi kĂ”ik ĂŒhtemoodi. Kui olete esmakordselt öelnud, et see on teil number, ja teisel korral öelnud, et see on VARCHAR, siis ei saa Server-prepared statements'i uuesti kasutada. Sellisel juhul tuleb meie statement jĂ€lle uuesti luua.

PostgreSQL ja JDBC pigistame vÀlja iga tilka. Vladimir Sitnikov

Kui tĂ€idate sama pĂ€ringut, siis jĂ€lgige, et andmetĂŒĂŒbid veergudes ei seguneks. Peab jĂ€lgima NULL-i. See on sage viga, mis meil esines pĂ€rast PreparedStatements'i kasutuselevĂ”ttu.

PostgreSQL ja JDBC pigistame vÀlja iga tilka. Vladimir Sitnikov

HĂ€sti, lĂŒlitasime sisse. VĂ”ib-olla kasutasime draiverit. Ja jĂ”udlus langes. KĂ”ik muutus halvaks.

Kuidas see on vĂ”imalik? Kas see on bug vĂ”i funktsioon? Kahjuks ei Ă”nnestunud mĂ”ista – kas see on bug vĂ”i funktsioon. Aga on tĂ€iesti lihtne stsenaarium, kuidas seda probleemi paljundada. See ootamatult pĂŒĂŒdis meid kinni. Ja seisneb valimises, mis on praktiliselt ainult ĂŒhest tabelist. Meil oli muidki selliseid pĂ€ringuid. Need sisaldasid reeglina kahte-kolme tabelit, kuid siin on selline paljundamissenaarium. VĂ”tke oma andmebaasist mis tahes versioon ja paljundage.

PostgreSQL ja JDBC pigistame vÀlja iga tilka. Vladimir Sitnikov

https://gist.github.com/vlsi/df08cbef370b2e86a5c1

MĂ”te on selles, et meil on kaks veergu, millest kummaski on indeks. Ühes veerus on NULL-i vÀÀrtus miljon rida. Teises veerus on vaid 20 rida. Kui tĂ€idame ilma sidumata muutujateta, siis kĂ”ik töötab hĂ€sti.

Kui hakkame tÀitma sidustatud muutujatega, st tÀidame mÀrgi "?" vÔi "$1" meie pÀringule, siis mida me lÔpuks saame?

PostgreSQL ja JDBC pigistame vÀlja iga tilka. Vladimir Sitnikov

https://gist.github.com/vlsi/df08cbef370b2e86a5c1

Esimene tĂ€itmine – nagu alati. Teine – natuke kiiremini. Midagi vahemĂ€llu salvestus. Kolmas-neljanda viies. Siis plahvatab – ja just nii. Ja kĂ”ige halvem on see, et see juhtub kuuendal tĂ€itmisel. Kes teadis, et peab tegema just kuus tĂ€itmist, et aru saada, milline seal reaalselt tĂ€itmisplaan on?

PostgreSQL ja JDBC pigistame vÀlja iga tilka. Vladimir Sitnikov

Kes on sĂŒĂŒdi? Mis juhtus? Andmebaas sisaldab optsioonide optimeerimist. Ja see on nagu optimeeritud ĂŒldiseks olukorraks. SeetĂ”ttu, alates mingist hetkest, liigub ta ĂŒldisele plaanile, mis, kahjuks, vĂ”ib osutuda teistsuguseks. Ta vĂ”ib osutuda samaks vĂ”i teistsuguseks. Seal on mingi kĂŒnnisvÀÀrtus, mis toob kaasa sellise kĂ€itumise.

Mida sellega teha? Siin on tĂ”enĂ€oliselt keerulisem midagi oletada. On lihtne lahendus, mida me kasutame. See on +0, OFFSET 0. Kindlasti teate selliseid lahendusi. Lihtsalt vĂ”tame ja lisame pĂ€ringusse „+0” ja kĂ”ik on hĂ€sti. NĂ€itan hiljem.

Ja on veel variant – vaadata hoolikamalt plaane. Arendaja peab mitte ainult pĂ€ringut kirjutama, vaid ka 6 korda ĂŒtlema „explain analyze”. Kui 5, siis ei sobi.

Ja on veel kolmas variant – kirjutada pgsql-hackers-le kiri. Ma kirjutasin, tĂ”si kĂŒll, hetkel ei ole selge – kas see on viga vĂ”i omadus.

PostgreSQL ja JDBC pigistame vÀlja iga tilka. Vladimir Sitnikov

https://gist.github.com/vlsi/df08cbef370b2e86a5c1

Kuni me mĂ”tleme – kas see on viga vĂ”i omadus, lahendame probleemid. VĂ”tame meie pĂ€ringu ja lisame „+0”. KĂ”ik on hĂ€sti. Kaks mĂ€rki ja isegi ei pea mĂ”tlema, kuidas ja mis seal on. VĂ€ga lihtne. Me lihtsalt kĂ€skisime andmebaasil mitte kasutada indeksi selle veeru jaoks. Meil ei ole indeksi veert „+0” ja kĂ”ik, andmebaas ei kasuta indeksit, kĂ”ik on hĂ€sti.

PostgreSQL ja JDBC pigistame vÀlja iga tilka. Vladimir Sitnikov

Siin on reegel 6 explain'ist. Hetkel kÀesolevates versioonides tuleb teha 6 korda, kui teil on seotud muutujad. Kui teil ei ole seotud muutujaid, siis teeme nii. Ja meil lÔpuks tÀpselt see pÀring kukub. Asi pole keeruline.

Tundub, kui kaua saab? Siin on viga, seal on viga. Tegelikult on viga igal pool.

PostgreSQL ja JDBC pigistame vÀlja iga tilka. Vladimir Sitnikov

Vaatame veel. NĂ€iteks, meil on kaks skeemi. Skeem A tabeliga Đ« ja skeem B sama tabeliga Đ«. PĂ€ring – valida andmed tabelist. Mis meil sellega on? Meil on viga. Meil on kĂ”ik eelnevalt loetletud. Reegel on selline – viga igal pool, meil on kĂ”ik eelnevalt loetletud.

PostgreSQL ja JDBC pigistame vÀlja iga tilka. Vladimir Sitnikov

NĂŒĂŒd kĂŒsimus: „Miks?”. Tundub, et on dokumentatsioon, et kui meil on skeem, siis on muutuja „search_path”, mis ĂŒtleb, kus peab otsima tabelit. Tundub, et muutuja on olemas.

Mis on probleem? Probleem on selles, et serveri valmistatud avaldused ei kahtle, et search_pathi vÔib keegi muuta. See vÀÀrtus jÀÀb andmebaasi jaoks nagu konstantseks. Ja mÔned osad ei pruugi haarata uusi vÀÀrtusi.

PostgreSQL ja JDBC pigistame vÀlja iga tilka. Vladimir Sitnikov

Loomulikult sÔltub see versioonist, millega te testite. See sÔltub ka sellest, kui ulatuslikud teie tabelid on. Versioon 9.1 kÀivitab lihtsalt vanad pÀringud. Uuemad versioonid vÔivad aga avastada petu ja öelda, et teil on viga.

PostgreSQL ja JDBC pigistame vÀlja iga tilka. Vladimir Sitnikov

Seadke search_path + serveri ettevalmistatud laused =
vahemĂ€lu plaan ei tohi muuta tulemuste tĂŒĂŒpi

Kuidas seda parandada? Lihtne retsept – Ă€rge tehke nii. Ärge muutke search_path'i rakenduse töö kĂ€igus. Kui muudate, siis on parem luua uus ĂŒhendus.

Saame arutada, st avada, arutada ja kirjutada juurde. VĂ”ib-olla suudame veenda andmebaasi arendajaid, et juhul, kui keegi muudab vÀÀrtust, peaks andmebaas sellest kliendile teatama: „Vaadake, teie vÀÀrtus on siin uuendatud. Kas peaksite statements'id lĂ€htestama, uuesti looma?”. Praegu kĂ€itub andmebaas salaja ja ei teata mingil moel, et kuskil sees on statements'id muutunud.

Ja ma rĂ”hutan taas – see pole Java puhul tĂŒĂŒpiline. NĂ€eme seda sama ka PL/pgSQL'is sĂ”na-sĂ”nalt. Seal see ka kordub.

PostgreSQL ja JDBC pigistame vÀlja iga tilka. Vladimir Sitnikov

Proovime veel andmeid valida. Valime, valime. Meil on tabel, kus on miljon rida. Iga rida ĂŒks kilobait. Umbes gigabait andmeid. Ja meil on Java masina töötav mĂ€lu 128 megabaiti.

Kasutame nagu kÔikides raamatutes soovitatakse voogedastust. St avame resultSet ja loeme sealt andmeid tasapisi. Kas see töötab? Kas see ei kuku mÀlu tÔttu? Kas see loeb natuke? Usume andmebaasi, usume Postgressesse. Ei usu. Kukume OutOfMemory? Kes on kukkunud OutOfMemory? Ja kes suutis pÀrast seda parandada? Keegi suutis parandada.

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Àngida?

Siin, nagu tavaliselt, osutub kĂ”ige ootamatum variant Ă”igeks. Ja kui te Ă€kitselt lĂŒlitate autoCommit'i vĂ€lja, siis see aitab. Miks nii? Teadusele see ei ole teada.

PostgreSQL ja JDBC pigistame vÀlja iga tilka. Vladimir Sitnikov

Aga vaikimisi valivad kĂ”ik kliendid, kes ĂŒhenduvad Postgres andmebaasiga, andmeid tervikuna. PgJDBC selle osas pole erand, valib kĂ”ik read.

On variatsioon FetchSize'il, st saate eraldi statements'i tasandil öelda, et siit palun valige andmeid 10, 50. Kuid see ei tööta, kuni te ei lĂŒlita autoCommit'i vĂ€lja. LĂŒlitasite autoCommit'i vĂ€lja – hakkab tööle.

Koodi lĂ€bimine ja igal pool setFetchSize seadmine on ebamugav. SeetĂ”ttu tegime sellise seadistuse, mis mÀÀrab vaikimisi vÀÀrtuse kogu ĂŒhenduse jaoks.

PostgreSQL ja JDBC pigistame vÀlja iga tilka. Vladimir Sitnikov

Nii et me seda ĂŒtlesime. Seadisime parameetri. Ja mis me nĂŒĂŒd saime? Kui valime vĂ€ikese, nĂ€iteks 10 rida, siis on meie kulud ĂŒsna suured. SeetĂ”ttu peaksime selle vÀÀrtuse seadma umbes sajale.

PostgreSQL ja JDBC pigistame vÀlja iga tilka. Vladimir Sitnikov

Ideaalis vĂ”iksime muidugi Ă”ppida piirama ka baitides, aga retsept on selline: seab defaultRowFetchSize ĂŒle saja ja oleme rahul.

PostgreSQL ja JDBC pigistame vÀlja iga tilka. Vladimir Sitnikov

Liigume andmete sisestamise juurde. Sisestamine on lihtsam, seal on erinevaid variante. NĂ€iteks, INSERT, VALUES. See on hea variant. VĂ”ime rÀÀkida "INSERT SELECT". Praktikas on need ĂŒks ja sama. Erinevust jĂ”udluses ei ole.

Raamatud ĂŒtlevad, et tuleb tĂ€ita Batch statement, raamatud ĂŒtlevad, et vĂ”ib tĂ€ita keerulisemaid kĂ€ske mitme sulgudega. Ja Postgres'is on suurepĂ€rane funktsioon - vĂ”ib teha COPY, st teha seda kiiremini.

PostgreSQL ja JDBC pigistame vÀlja iga tilka. Vladimir Sitnikov

Kui mÔÔta, vÔib teha uuesti mitmeid huvitavaid avastusi. Kuidas me tahame, et see töötab? Tahame mitte parsida ja mitte tÀiendavaid kÀske tÀita.

PostgreSQL ja JDBC pigistame vÀlja iga tilka. Vladimir Sitnikov

Praktikas ei lase TCP meil nii teha. Kui klient on hÔivatud pÀringu saatmisega, siis andmebaas proovib meile vastuseid saata, aga pÀringuid ei loeta. LÔpuks ootab klient andmebaasi, kuni see pÀringu loeb, samal ajal kui andmebaas ootab klienti, kuni see vastuse loeb.

PostgreSQL ja JDBC pigistame vÀlja iga tilka. Vladimir Sitnikov

SeetĂ”ttu peab klient perioodiliselt saatma sĂŒnkroniseerimise paketi. Üksikud vĂ”rgu suhtlused, aeglane ajakadu.

PostgreSQL ja JDBC pigistame vĂ€lja iga tilka. Vladimir SitnikovJa mida rohkem me neid lisame, seda halvemaks lĂ€heb. Draiver on ĂŒsna pessimistlik ja lisab neid ĂŒsna sageli, umbes iga 200 rea jĂ€rel, sĂ”ltuvalt ridade suurusest jms.

PostgreSQL ja JDBC pigistame vÀlja iga tilka. Vladimir Sitnikov

https://github.com/pgjdbc/pgjdbc/pull/380

Juhtub, et parandad ĂŒhte rida ja kĂ”ik kiireneb 10 korda. Nii juhtub. Miks? Nagu tavaliselt, mingi konstandi oli seal juba kasutatud. Ja vÀÀrtus „128” tĂ€hendas - mitte kasutada batchingut.

PostgreSQL ja JDBC pigistame vÀlja iga tilka. Vladimir Sitnikov

Java microbenchmark harness

Hea, et see ei sattunud ametlikku versioonisse. Leidsime selle enne, kui hakkasime vÀlja andma vÀljaannet. KÔik vÀÀrtused, mida ma nimetan, pÔhinevad kaasaegsetel versioonidel.

PostgreSQL ja JDBC pigistame vÀlja iga tilka. Vladimir Sitnikov

MÔÔgame. Me mÔÔdame lihtsat InsertBatch'i. Me mÔÔdame mitmekordset InsertBatch'i, st sama asi, kuid palju values. Kaval kÀik. Mitte kÔik ei oska nii teha, aga see on lihtne kÀik, palju lihtsam kui COPY.

PostgreSQL ja JDBC pigistame vÀlja iga tilka. Vladimir Sitnikov

Saab teha COPY.

PostgreSQL ja JDBC pigistame vÀlja iga tilka. Vladimir Sitnikov

Ja saab seda teha struktuurides. Deklareeri kasutaja vaikimisi tĂŒĂŒp, edastades massiivi ja INSERT otse tabelisse.

Kui avate lingi: pgjdbc/ubenchmsrk/InsertBatch.java, siis see kood on GitHubis. Saate vaadata tÀpselt, milliseks pÀringud seal genereeritakse. See ei ole olulised.

PostgreSQL ja JDBC pigistame vÀlja iga tilka. Vladimir Sitnikov

Me kĂ€ivitasime selle. Ja esimene asi, mille me mĂ”istsime, oli see, et batchi mittekasutamine on lihtsalt vĂ€listatud. KĂ”ik batchimise variandid on nullid, st tĂ€itmise aeg on praktiliselt null vĂ”rreldes ĂŒhekordse tĂ€itmisega.

PostgreSQL ja JDBC pigistame vÀlja iga tilka. Vladimir Sitnikov

Me sisestame andmed. Seal on vÀga lihtne tabel. Kolm veergu. Ja mida me siin nÀeme? Me nÀeme, et kÔik need kolm varianti on umbes vÔrreldavad. Ja COPY on loomulikult parem.

PostgreSQL ja JDBC pigistame vÀlja iga tilka. Vladimir Sitnikov

See, kui me tĂŒkikaupa sisestame. Kui me rÀÀkisime, et ĂŒks vÀÀrtus VALUES, kaks vÀÀrtust VALUES, kolm vÀÀrtust VALUES vĂ”i kui me neid 10 komaga nimetasime. See peaks olema nĂŒĂŒd horisontaalsel tasandil. 1, 2, 4, 128. On nĂ€ha, et Batch Insert, mis on siniseks joonistatud, muudab asja kergemaks. St kui sisestate ĂŒkshaaval vĂ”i isegi nelja kaupa, siis see aitab kahel korral paremini, lihtsalt seetĂ”ttu, et me panime VALUESisse veidi rohkem. VĂ€hem EXECUTE operatsioone.

Kopeerimise kasutamine vÀikeste mahtude korral on ÀÀrmiselt vÀhelootustandev. Ma ei joonistanud isegi kahe esimesega. Need lÀhevad taevasse, st need rohelised numbrid jaoks COPY.

COPY-d tuleks kasutada, kui teie andmemaht on vĂ€hemalt ĂŒle saja rea. Ühenduse avamise kulud on suured. Ja, ausalt öeldes, ma ei ole selle poolega sĂŒvenenud. Batch'i optimeerisin, COPY-d mitte.

Mida me edasi teeme? Me mÔÔdame. Saame aru, et peame kasutama kas struktuure vÔi nutikat batching'u, mis liidab mitu vÀÀrtust.

PostgreSQL ja JDBC pigistame vÀlja iga tilka. Vladimir Sitnikov

Mida tuleb tÀnasest ettekandest vÀlja tuua?

  • PreparedStatement – see on meie kĂ”ik. See toob vĂ€ga palju kaasa jĂ”udlusele. See toob suure alusikka.
  • Ja tuleb teha EXPLAIN ANALYZE 6 korda.
  • Ja tuleb lahjendada OFFSET 0 ning trikkidega nagu +0, et korvata veel jÀÀnud protsent meie probleemsetest pĂ€ringutest.

Allikas: habr.com

Osta usaldusvÀÀrne hostimine veebilehtede jaoks DDoS-i kaitsega, VPS VDS serverid đŸ”„ Osta usaldusvÀÀrne hostimine veebilehtede jaoks DDoS-i kaitsega, VPS VDS serverid | ProHoster