PostgreSQL kontsulten optimizazioa masiboa. Kirill Borovikov (Tentsorea)

Txostenak aukera ematen duten planteamendu batzuk aurkezten ditu kontrolatu SQL kontsulten errendimendua egunean milioika daudenean, eta ehunka monitorizatutako PostgreSQL zerbitzari daude.

Zein irtenbide teknikok ahalbidetzen digute informazio-bolumen hori modu eraginkorrean prozesatzeko, eta nola errazten du horrek garatzaile arrunt baten bizitza?


Nori interesatzen zaio? problema zehatzak eta optimizazio teknika ezberdinak aztertzea SQL kontsultak eta PostgreSQL-n DBA ohiko arazoak konpontzea ere egin dezakezu artikulu sorta bat irakurri gai honen inguruan.

PostgreSQL kontsulten optimizazioa masiboa. Kirill Borovikov (Tentsorea)
Nire izena Kirill Borovikov da, ordezkatzen dut Tensor konpainia. Zehazki, gure enpresan datu-baseekin lan egiten espezializatu naiz.

Gaur kontsultak nola optimizatzen ditugun kontatuko dizut, ez duzunean kontsulta bakar baten errendimendua "bereiztu" behar, baina arazoa masiboki konpontzen. Milioika eskaera daudenean, eta batzuk aurkitu behar dituzunean konponbiderako planteamenduak arazo handi hau.

Oro har, gure bezeroetako milioi batentzako Tensor da VLSI gure aplikazioa da: sare sozial korporatiboa, bideo-komunikaziorako soluzioak, barneko eta kanpoko dokumentu-fluxurako, kontabilitate-sistemak eta biltegietarako kontabilitate-sistemak,... Hau da, halako β€œmega-konbinazio” bat enpresen kudeaketa integralerako, zeinetan 100 baino gehiago dauden. barne proiektuak.

Guztiek normal funtzionatzen eta garatzen dutela ziurtatzeko, 10 garapen-zentro ditugu herrialde osoan, eta horietan gehiago daude 1000 garatzaile.

2008az geroztik PostgreSQLrekin lan egiten dugu eta prozesatzen dugunaren kopuru handia pilatu dugu - bezeroen datuak, estatistikak, analitikoak, kanpoko informazio sistemetako datuak - 400TB baino gehiago. 250 zerbitzari inguru daude ekoizpenean bakarrik, eta guztira 1000 datu-base zerbitzari inguru daude kontrolatzen ditugunak.

PostgreSQL kontsulten optimizazioa masiboa. Kirill Borovikov (Tentsorea)

SQL hizkuntza deklaratiboa da. Ez duzu zerbaitek "nola" funtzionatu behar duen deskribatzen, "zer" lortu nahi duzun baizik. DBMSk hobeto daki JOIN bat nola egin: zure taulak nola konektatu, zer baldintza ezarri, zer indizetik pasatuko den, zer ez...

DBMS batzuek aholkuak onartzen dituzte: "Ez, konektatu bi mahai hauek halako eta halako ilara batean", baina PostgreSQL-k ezin du hau egin. Hau da garatzaile nagusien jarrera kontzientea: "Nahiago dugu kontsulta-optimizatzailea amaitzea, garatzaileei aholku batzuk erabiltzeko baimena ematea baino".

Baina, PostgreSQL-k "kanpoak" bere burua kontrolatzen uzten ez duen arren, ezin hobeto onartzen du ikusi zer gertatzen zaion barruanzure kontsulta exekutatzen duzunean eta non arazoak dituen.

PostgreSQL kontsulten optimizazioa masiboa. Kirill Borovikov (Tentsorea)

Oro har, zer arazo klasiko ditu garatzaile batek [DBA bati] normalean? Β«Hemen bete genuen eskaera, eta dena motel doa gurekin, dena zintzilik dago, zerbait gertatzen ari da... Arazoren bat!Β».

Arrazoiak ia beti berdinak dira:

  • kontsulta-algoritmo ez eraginkorra
    Garatzailea: "Orain 10 taula ematen dizkiot SQL-n JOIN bidez..." - eta espero du bere baldintzak modu eraginkorrean "askatu" egingo direla eta dena azkar lortuko duela. Baina mirariak ez dira gertatzen, eta halako aldakortasuna duen edozein sistemak (10 taula FROM batean) beti ematen du nolabaiteko errorea. [artikuluan]
  • garrantzirik gabeko estatistikak
    Puntu hau oso garrantzitsua da PostgreSQLrentzat bereziki, datu-multzo handi bat zerbitzarira "isuri" duzunean, eskaera bat egin eta zure tableta "sexcan" egiten duzunean. Atzo 10 erregistro zeudelako bertan, eta gaur 10 milioi, baina PostgreSQL oraindik ez da horren berri, eta horren berri eman behar dugu. [artikuluan]
  • baliabideetan "entxufatu".
    Disko, memoria edo prozesadorearen errendimendu nahikorik ez duen zerbitzari ahul batean datu-base handi eta karga handia instalatu duzu. Eta hori da dena... Nonbait errendimenduko sabai bat dago, zeinaren gainetik ezin duzu jauzi.
  • blokeatzea
    Puntu zaila da hau, baina garrantzitsuenak dira hainbat aldaketetarako (txertatu, EGUNERATU, EZABATU) - hau aparteko gai handi bat da.

Plan bat lortzea

...Eta beste guztietarako guk plan bat behar! Zerbitzariaren barruan zer gertatzen den ikusi behar dugu.

PostgreSQL kontsulten optimizazioa masiboa. Kirill Borovikov (Tentsorea)

PostgreSQL-ren kontsultak exekutatzeko plan bat testuen irudikapenean kontsultak exekutatzeko algoritmoaren zuhaitza da. Algoritmoa da, hain zuzen ere, planifikatzaileak egindako analisiaren ondorioz, eraginkorrena.

Zuhaitz-nodo bakoitza eragiketa bat da: taula edo indize batetik datuak berreskuratzea, bit-mapa bat eraikitzea, bi taula elkartzea, hautaketak elkartu, gurutzatzea edo baztertzea. Kontsulta bat exekutatzeak zuhaitz honen nodoetatik ibiltzea dakar.

Kontsulta-plana lortzeko, modurik errazena adierazpena exekutatzen da EXPLAIN. Benetako atributu guztiekin lortzeko, hau da, oinarrian kontsulta bat benetan exekutatzeko - EXPLAIN (ANALYZE, BUFFERS) SELECT ....

Alde txarra: exekutatzen duzunean, "hemen eta orain" gertatzen da, beraz, tokiko arazketarako bakarrik da egokia. Oso kargatutako zerbitzari bat hartzen baduzu datu-aldaketen fluxu handian dagoena, eta ikusten baduzu: "Oh! Hemen exekuzio motela duguXia eskaera". Duela ordu erdi, ordu bat - exekutatzen ari zinela eta erregistroetatik eskaera hau jasotzen, zerbitzarira itzultzen ari zinela, zure datu multzo osoa eta estatistikak aldatu ziren. Exekutatzen duzu arazketa egiteko - eta azkar exekutatzen da! Eta ezin duzu ulertu zergatik, zergatik zen poliki-poliki.

PostgreSQL kontsulten optimizazioa masiboa. Kirill Borovikov (Tentsorea)

Eskaera zerbitzarian exekutatu zen unean zer gertatu zen zehazki ulertzeko, jende adimendunek idatzi zuten auto_azaldu modulua. PostgreSQL banaketa ohikoenetan dago eta konfigurazio fitxategian besterik gabe aktibatu daiteke.

Eskaera batzuk esandako muga baino luzeago exekutatzen ari direla konturatzen bada, hala egiten du Eskaera honen planoaren β€œinstantanea” eta elkarrekin idazten ditu erregistroan.

PostgreSQL kontsulten optimizazioa masiboa. Kirill Borovikov (Tentsorea)

Badirudi dena ondo dagoela orain, erregistrora joan eta hor ikusten dugu... [testu oinetakoa]. Baina ezin dugu ezer esan horretaz, plan bikaina dela exekutatzeko 11 ms behar izan dituelako.

Dena ondo dagoela dirudi, baina ezer ez dago argi benetan zer gertatu den. Ordu orokorraz gain, ez dugu ezer ikusten. Testu arrunteko halako "bildotsa" ikustea, oro har, ez baita bisuala.

Baina agerikoa ez bada ere, deserosoa bada ere, oinarrizko arazo gehiago daude:

  • Nodoak adierazten du azpizuhaitz osoaren baliabideen batura haren azpian. Hau da, ezin duzu aurkitu Indizearen eskaneatu zehatz honetan zenbat denbora eman den horren azpian habiaratuta dagoen baldintzaren bat badago. Dinamikoki begiratu behar dugu ea β€œseme-alabak” eta baldintzazko aldagaiak, CTEak barruan dauden ikusteko eta hori guztia β€œgure buruan” kendu.
  • Bigarren puntua: nodoan adierazten den denbora da nodo bakarreko exekuzio denbora. Nodo hau, adibidez, hainbat aldiz taulako erregistroen bidez exekutatu bada, orduan begizta kopurua β€”nodo honen zikloakβ€” handitzen da planoan. Baina exekuzio-denbora atomikoa bera izaten jarraitzen du planari dagokionez. Hau da, nodo hau guztira zenbat denbora egin zen ulertzeko, gauza bat beste batekin biderkatu behar duzu - berriro, "zure buruan".

Horrelako egoeretan, ulertu "Nor da katerik ahulena?" ia ezinezkoa. Hori dela eta, garatzaileek beraiek ere "eskuliburuan" idazten dute β€œPlan bat ulertzea ikasi beharreko artea da, esperimentatu...”.

Baina 1000 garatzaile ditugu, eta ezin diozu esperientzia hori helarazi horietako bakoitzari. Nik, zuk, berak badaki, baina hango batek jada ez daki. Agian ikasiko du, edo agian ez, baina orain lan egin behar du, eta nondik aterako luke esperientzia hori?

Planaren bistaratzea

Hori dela eta, konturatu ginen arazo horiei aurre egiteko behar dugula planaren bistaratzea ona. [Artikulu]

PostgreSQL kontsulten optimizazioa masiboa. Kirill Borovikov (Tentsorea)

Lehenik eta behin "merkatutik" joan ginen; ikus dezagun Interneten zer dagoen ikusteko.

Baina konturatu zen oso gutxi edo gutxi garatzen ari diren irtenbide nahiko "bizi" gutxi daudela - literalki, bakarra: azaldu.depesz.com Egilea: Hubert Lubaczewski. "Jarioa" eremuan planaren testuaren irudikapena sartzen duzunean, taula bat erakusten dizu analizatutako datuekin:

  • nodoaren prozesatzeko denbora
  • azpizuhaitz osoaren denbora osoa
  • Estatistikoki espero zirenak berreskuratu ziren erregistro kopurua
  • nodoaren gorputza bera

Zerbitzu honek esteken artxiboa partekatzeko aukera ere badu. Zure plana bertan sartu eta esan zenuen: "Aizu, Vasya, hemen duzu esteka bat, zerbait gaizki dago".

PostgreSQL kontsulten optimizazioa masiboa. Kirill Borovikov (Tentsorea)

Baina arazo txikiak ere badaude.

Lehenik eta behin, "kopiatu-itsatsi" kopuru handia. Enbor zati bat hartu, han itsatsi eta berriro, eta berriro.

Bigarrenik, irakurritako datu kopuruaren azterketarik ez β€” Irteerako buffer berdinak EXPLAIN (ANALYZE, BUFFERS), ez dugu hemen ikusten. Besterik gabe, ez daki nola desmuntatu, ulertzen eta haiekin lan egin. Datu asko irakurtzen ari zarenean eta diskoa eta memoria cachea gaizki esleitzen ari zarela konturatzen zarenean, informazio hori oso garrantzitsua da.

Hirugarren puntu negatiboa proiektu honen garapen oso ahula da. Konpromisoak oso txikiak dira, ona da sei hilabetean behin bada, eta kodea Perl-en dago.

PostgreSQL kontsulten optimizazioa masiboa. Kirill Borovikov (Tentsorea)

Baina hau dena "letra" da, nolabait bizi gintezke honekin, baina bada gauza bat zerbitzu honetatik asko urrundu gaituena. Hauek Common Table Expression (CTE) eta InitPlan/SubPlan bezalako hainbat nodo dinamikoen analisian egindako erroreak dira.

Irudi hau sinesten baduzu, nodo bakoitzaren exekuzio-denbora osoa eskaera osoaren exekuzio-denbora baino handiagoa da. Sinplea da - CTE honen sorrera-denbora ez zen kendu CTE Scan nodotik. Hori dela eta, jada ez dakigu erantzun zuzena zein den CTE eskaneak berak zenbat denbora iraun zuen.

PostgreSQL kontsulten optimizazioa masiboa. Kirill Borovikov (Tentsorea)

Orduan konturatu ginen geureak idazteko ordua zela - tira! Garatzaile guztiek esaten dute: "Orain gurea idatziko dugu, oso erraza izango da!"

Web zerbitzuetarako ohiko pila bat hartu genuen: Node.js + Express-en oinarritutako nukleoa, Bootstrap eta D3.js erabili zituen diagrama ederetarako. Eta gure itxaropenak guztiz justifikatuta zeuden - 2 astetan jaso genuen lehen prototipoa:

  • pertsonalizatutako plan analizatzailea
    Hau da, orain PostgreSQL-ek sortutako edozein plan analizatu dezakegu.
  • nodo dinamikoen azterketa zuzena - CTE Scan, InitPlan, AzpiPlan
  • Buffer banaketaren analisia - non datu-orriak memoriatik irakurtzen diren, non tokiko cachetik, non diskotik
  • argitasuna lortu zuen
    Hori guztia erregistroan ez "zulatzeko", baizik eta argazkian "estekarik ahulena" berehala ikusteko.

PostgreSQL kontsulten optimizazioa masiboa. Kirill Borovikov (Tentsorea)

Horrelako zerbait lortu dugu, sintaxia nabarmentzea barne. Baina normalean gure garatzaileek ez dute planaren irudikapen osoa lan egiten, laburrago batekin baizik. Azken finean, dagoeneko zenbaki guztiak analizatu ditugu eta ezker-eskuin bota ditugu, eta erdian lehen lerroa bakarrik utzi dugu, nolako nodoa den: CTE Scan, CTE generation edo Seq Scan zeinu batzuen arabera.

Hau da deitzen dugun irudikapen laburtua plan txantiloia.

PostgreSQL kontsulten optimizazioa masiboa. Kirill Borovikov (Tentsorea)

Zer gehiago litzateke komenigarria? Komenigarria litzateke ikustea gure denbora osoaren zein parte den zein nodori esleitzen zaion - eta alboan "itsatsi" besterik ez. diagrama.

Nodoa seinalatzen dugu eta ikusten dugu: Seq Scan denbora osoaren laurdena baino gutxiago hartu zuela eta gainerako 3/4 CTE Scan-ek hartu zuen. Izua! Hau CTE Scan-en "su-mailari" buruzko ohar txiki bat da, zure kontsultetan aktiboki erabiltzen badituzu. Ez dira oso azkarrak - mahai arrunten eskaneatzea baino txikiagoak dira. [Artikulu] [Artikulu]

Baina normalean halako diagramak interesgarriagoak, konplexuagoak dira, berehala segmentu bat seinalatzen dugunean eta ikusten dugunean, adibidez, denboraren erdia baino gehiago Seq Scan batzuk "jaten" dutela. Gainera, barruan Filter moduko bat zegoen, disko asko baztertu ziren horren arabera... Zuzenean argazki hau bota diezaiokezu garatzaileari eta esan: β€œVasya, hemen dena txarto dago zuretzat! Asmatu, begira, zerbait gaizki dago!Β».

PostgreSQL kontsulten optimizazioa masiboa. Kirill Borovikov (Tentsorea)

Jakina, tartean "raska" batzuk zeuden.

Topatu genuen lehenengo gauza biribilketa arazoa izan zen. Planoko nodo bakoitzaren denbora 1 ΞΌs-ko zehaztasunarekin adierazten da. Eta nodo-ziklo kopurua gainditzen denean, adibidez, 1000 - exekutatu ondoren PostgreSQL-k "zehaztasun barruan" zatitu zuen, orduan atzera kalkulatzean denbora osoa "0.95 ms eta 1.05 ms artean" lortzen dugu. Zenbaketa mikrosegundoetara doanean, ondo dago, baina dagoeneko [mili]segundoak direnean, informazio hori kontuan hartu behar duzu baliabideak "askotatzerakoan" "nork zenbat kontsumitu du" planaren nodoetan.

PostgreSQL kontsulten optimizazioa masiboa. Kirill Borovikov (Tentsorea)

Bigarren puntua, konplexuagoa, baliabideak (buffer horiek) nodo dinamikoen artean banatzea da. Honek prototipoaren lehen 2 asteak gehi beste 4 aste kostatu zitzaizkigun.

Nahiko erraza da arazo mota hau lortzea: CTE bat egiten dugu eta ustez bertan zerbait irakurtzen dugu. Izan ere, PostgreSQL "adimentsua" da eta ez du zuzenean ezer irakurriko bertan. Gero, bertatik lehenengo diskoa hartzen dugu, eta hari CTE bereko ehun eta lehenengoa.

PostgreSQL kontsulten optimizazioa masiboa. Kirill Borovikov (Tentsorea)

Planari begiratu eta ulertzen dugu - bitxia da, 3 buffer (datu-orri) "kontsumituta" ditugu Seq Scan-en, beste 1 CTE Scan-en eta beste 2 CTE Scan bigarrenean. Hau da, dena laburbilduz gero, 6 lortuko ditugu, baina tabletetik 3 besterik ez ditugu irakurtzen! CTE Scan-ek ez du ezer irakurtzen inondik inora, baina zuzenean funtzionatzen du prozesuko memoriarekin. Hau da, argi dago zerbait gaizki dagoela hemen!

Izan ere, hona hemen Seq Scan-etik eskatutako datu 3 orri horiek guztiak, lehenengo 1ek 1. CTE Scan-a eskatu zuen, eta gero 2.a, eta beste 2 irakurri zizkiotela. Hau da, guztira. 3 orrialde irakurri ziren datuak, ez 6.

PostgreSQL kontsulten optimizazioa masiboa. Kirill Borovikov (Tentsorea)

Eta argazki honek ulertzera eraman gintuen plano baten exekuzioa jada ez dela zuhaitz bat, grafiko azikliko moduko bat besterik ez dela. Eta honelako diagrama bat lortu genuen, "lehenik nondik etorri zena" ulertzeko. Hau da, hemen pg_class-etik CTE bat sortu genuen, eta bi aldiz eskatu genuen, eta ia denbora guztia adarrean eman genuen 2. aldiz eskatu genuenean. Argi dago 101. sarrera irakurtzea tabletetik 1. sarrera irakurtzea baino askoz garestiagoa dela.

PostgreSQL kontsulten optimizazioa masiboa. Kirill Borovikov (Tentsorea)

Pixka bat bota genuen. Esan zuten: "Orain, Neo, badakizu kung fu! Orain gure esperientzia zure pantailan dago. Orain erabil dezakezu". [Artikulu]

Erregistroak finkatzea

Gure 1000 garatzaileek lasaitu zuten. Baina ulertu genuen ehunka "borroka" zerbitzari baino ez ditugula, eta garatzaileen "kopia-itsatsi" hori guztia ez da batere komenigarria. Guk geuk bildu behar genuela konturatu ginen.

PostgreSQL kontsulten optimizazioa masiboa. Kirill Borovikov (Tentsorea)

Oro har, estatistikak bil ditzakeen modulu estandar bat dago, hala ere, konfigurazioan ere aktibatu behar da - hau pg_stat_statements modulua. Baina ez zitzaigun egokitu.

Lehenik eta behin, kontsulta berdinak esleitzen ditu datu-base beraren eskema desberdinak erabiliz QueryId desberdinak. Hau da, lehenengo egiten baduzu SET search_path = '01'; SELECT * FROM user LIMIT 1;eta gero SET search_path = '02'; eta eskaera bera, orduan modulu honetako estatistikek erregistro desberdinak izango dituzte, eta ezin izango dut estatistika orokorrik bildu eskaera-profil horren testuinguruan zehazki, eskemak kontuan hartu gabe.

Erabiltzea galarazi zigun bigarren puntua da plan falta. Hau da, ez dago planik, eskaera bera baino ez dago. Zer moteltzen ari zen ikusten dugu, baina ez dugu ulertzen zergatik. Eta hemen azkar aldatzen ari den datu multzo baten arazora itzuliko gara.

Eta azken momentua - "gertaera" falta. Hau da, ezin duzu kontsultaren exekuzioaren instantzia zehatz bati zuzendu; ez dago bat ere, estatistikak agregatuak baino ez daude. Honekin lan egitea posible den arren, oso zaila da.

PostgreSQL kontsulten optimizazioa masiboa. Kirill Borovikov (Tentsorea)

Hori dela eta, copy-paste borrokatzea erabaki eta idazten hasi ginen biltzen.

Bilduma SSH bidez konektatzen da, datu-basearekin zerbitzariarekin konexio segurua ezartzen du ziurtagiri bat erabiliz, eta tail -F "Clings" horri log fitxategian. Beraz, saio honetan erregistro-fitxategi osoaren "ispilu" osoa lortuko dugu, zerbitzariak sortzen duena. Zerbitzarian bertan karga gutxienekoa da, ez dugulako ezer analizatzen bertan, trafikoa ispilu besterik ez dugu egiten.

Node.js-en interfazea idazten hasi ginenez, bildumagilea bertan idazten jarraitu genuen. Eta teknologia honek bere burua justifikatu du, oso erosoa delako JavaScript erabiltzea formatu ahuleko testu-datuekin lan egiteko, hau da, erregistroa. Eta Node.js azpiegiturak berak backend plataforma gisa erraz eta eroso lan egiteko aukera ematen du sareko konexioekin eta, hain zuzen ere, edozein datu-korronteekin.

Horren arabera, bi konexio "luzatzen" ditugu: lehenengoa erregistroa bera "entzuteko" eta geure buruari hartzeko, eta bigarrena aldian-aldian oinarriari galdetzeko. "Baina erregistroak erakusten du oid 123 duen seinalea blokeatuta dagoela", baina horrek ez dio ezer esan nahi garatzaileari, eta ondo legoke datu-baseari galdetzea: "Zer da OID = 123 hala ere?" Eta, beraz, aldian-aldian guri buruz oraindik ez dakiguna galdetzen diogu oinarriari.

PostgreSQL kontsulten optimizazioa masiboa. Kirill Borovikov (Tentsorea)

"Kontuan hartu ez duzun gauza bakarra dago, elefante-itxurako erle espezie bat dago!..." Sistema hau garatzen hasi ginen 10 zerbitzari kontrolatu nahi genituenean. Gure ulermenean kritikoena, non aurre egiteko zailak ziren arazo batzuk sortu ziren. Baina lehen hiruhilekoan ehun bat jaso genituen monitorizazioagatik: sistemak funtzionatu zuelako, denek nahi zuten, denak eroso zeuden.

Hori guztia batu egin behar da, datu-fluxua handia eta aktiboa da. Izan ere, kontrolatzen duguna, aurre egin diezaiokeguna, erabiltzen duguna da. PostgreSQL ere erabiltzen dugu datu biltegiratze gisa. Eta ezer ez da "isuri" datuak operadorea baino azkarrago COPY Oraindik ez.

Baina datuak "isurtzea" besterik gabe ez da gure teknologia. Ehun zerbitzaritan segundoko 50 eskaera gutxi gorabehera badituzu, honek 100-150 GB erregistro sortuko ditu egunean. Horregatik, kontu handiz "moztu" behar izan dugu oinarria.

Lehenik eta behin, egin genuen egunez banatzea, izan ere, orokorrean, inori ez zaio egunen arteko korrelazioa interesatzen. Zer desberdintasun du atzo izan zenuena, gaur gauean aplikazioaren bertsio berri bat zabaldu baduzu, eta dagoeneko estatistika berri batzuk.

Bigarrenik, ikasi genuen (behartuta egon ginen) oso-oso azkarra erabiliz idazteko COPY. Hau da, ez bakarrik COPYbaino azkarragoa delako INSERT, eta are azkarrago.

PostgreSQL kontsulten optimizazioa masiboa. Kirill Borovikov (Tentsorea)

Hirugarren puntua - egin behar nuen utzi abiarazleak, hurrenez hurren, eta kanpoko gakoak. Hau da, ez dugu batere osotasun erreferentziala. Zeren eta FK pare bat duen taula bat baduzu, eta datu-basearen egituran esaten baduzu "hemen FK-k erreferentzia egiten dion erregistro-erregistro bat, adibidez, erregistro-talde bati", txertatzen duzunean, PostgreSQL ez dauka ezer baino ez nola hartu eta zintzotasunez egin SELECT 1 FROM master_fk1_table WHERE ... txertatzen saiatzen ari zaren identifikatzailearekin - erregistro hau bertan dagoela egiaztatzeko, ez duzula "hausten" gako arrotz hau txertatzean.

Helburu-taulari eta bere indizeei erregistro bat eman beharrean, aipatzen dituen taula guztietatik irakurtzearen abantaila gehigarria lortzen dugu. Baina ez dugu hau batere behar - gure zeregina ahalik eta gehien eta ahalik eta azkarren karga gutxienarekin grabatzea da. Beraz, FK - behera!

Hurrengo puntua agregazioa eta hashinga da. Hasieran, datu-basean inplementatu genituen; azken finean, komenigarria da berehala, erregistro bat iristen denean, tablet motaren batean egitea. "gehi bat" abiarazlean. Beno, erosoa da, baina gauza txarra bera - erregistro bat sartzen duzu, baina beste taula batetik beste zerbait irakurtzera eta idaztera behartuta zaude. Gainera, irakurtzen eta idazten ez ezik, aldi oro ere egiten duzu.

Orain imajinatu taula bat duzula, non ostalari jakin batetik igaro diren eskaera kopurua zenbatzen besterik ez duzun: +1, +1, +1, ..., +1. Eta zuk, printzipioz, ez duzu hau behar - dena posible da bilduman memorian batura eta bidali datu-basera kolpe batean +10.

Bai, arazoren bat izanez gero, zure osotasun logikoa "desegin daiteke", baina kasu ia errealista da - zerbitzari normal bat duzulako, bateria bat daukazu kontrolagailuan, transakzioen erregistroa duzu, erregistro bat duzu. fitxategi-sistema... Oro har, ez du merezi. triggers/FK exekutatzen duzun produktibitatea galtzeak ez du balio egiten duzun gastua.

Berdin gertatzen da hashingarekin. Eskaera jakin bat hegan egiten dizu, datu-basean identifikatzaile jakin bat kalkulatzen duzu, datu-basean idatzi eta gero denei kontatu. Dena ondo dago, grabatzeko momentuan, gauza bera grabatu nahi duen bigarren pertsona bat etortzen zaizu arte, eta blokeatu egiten zaren arte, eta hori dagoeneko txarra da. Hori dela eta, ID batzuen sorrera bezeroari transferitu ahal bazaio (datu-baseari dagokionez), hobe da hau egitea.

Guretzat oso aproposa zen testutik MD5 erabiltzea - ​​eskaera, planoa, txantiloia,... Bilduma aldean kalkulatzen dugu, eta prest egindako IDa datu-basera "bota". MD5-ren luzerak eta eguneroko partizioak aukera ematen digu talka posibleez ez kezkatzeko.

PostgreSQL kontsulten optimizazioa masiboa. Kirill Borovikov (Tentsorea)

Baina hori guztia azkar grabatzeko, grabaketa prozedura bera aldatu behar genuen.

Nola idatzi ohi dituzu datuak? Nolabaiteko datu-multzo bat dugu, hainbat tauletan banatu dugu, eta gero KOPIATU - lehenengoan lehenengoan, gero bigarrenean, hirugarrenean... Deserosoa da, badirudi datu-korronte bat hiru pausotan idazten ari garela. sekuentzialki. Desatsegina. Azkar egin al daiteke? Ahal!

Horretarako, nahikoa da fluxu horiek elkarren paraleloan deskonposatzea. Ematen da akatsak, eskaerak, txantiloiak, blokeoak,... hari bereizietan hegan egiten ditugula eta dena paraleloan idazten dugu. Horretarako nahikoa mantendu COPY kanal bat etengabe irekita helburu-taula bakoitzarentzat.

PostgreSQL kontsulten optimizazioa masiboa. Kirill Borovikov (Tentsorea)

Hau da, bildumagilean beti dago korronte bat, eta bertan idatz ditzaket behar ditudan datuak. Baina datu-baseak datu hauek ikus ditzan eta norbait ez dadin trabatu datu hauek idazteko zain, COPY eten egin behar da tarte jakin batzuetan. Guretzat, aldi eraginkorrena 100 ms ingurukoa izan zen - itxi eta berehala irekitzen dugu mahai berera. Eta gailur batzuetan fluxu bat nahikoa ez badugu, orduan batzen dugu muga jakin batera.

Gainera, jakin dugu karga-profil baterako edozein agregazio, erregistroak loteka biltzen direnean, gaiztoa dela. Gaitz klasikoa da INSERT ... VALUES eta 1000 erregistro gehiago. Une horretan idazketa gailurra duzulako euskarrietan, eta diskoan zerbait idazten saiatzen diren beste guztiak zain egongo dira.

Horrelako anomaliak kentzeko, besterik gabe, ez gehitu ezer, ez buffer batere. Eta diskoan buffering-a gertatzen bada (zorionez, Node.js-eko Stream APIak jakiteko aukera ematen dizu) - atzeratu konexio hau. Berriro doakoa den gertaera bat jasotzen duzunean, idatzi hari metatutako ilaratik. Eta lanpetuta dagoen bitartean, hartu hurrengo doan igerilekutik eta idatzi.

Datuak grabatzeko ikuspegi hau sartu aurretik, gutxi gorabehera 4K idazketa-operazioak izan genituen, eta modu honetan karga 4 aldiz murriztu genuen. Orain beste 6 aldiz hazi dira kontrolatutako datu-base berrien ondorioz - 100 MB/s-ra arte. Eta orain azken 3 hilabeteetako erregistroak 10-15TB inguruko bolumenean gordetzen ditugu, hiru hilabetetan edozein garatzailek edozein arazo konpontzeko gai izango dela espero baitu.

Arazoak ulertzen ditugu

Baina datu horiek guztiak biltzea, besterik gabe, ona, erabilgarria, garrantzitsua da, baina ez nahikoa - ulertu behar da. Eguneko milioika plan ezberdin direlako.

PostgreSQL kontsulten optimizazioa masiboa. Kirill Borovikov (Tentsorea)

Baina milioika kudeaezinak dira, lehenik "txikiago" egin behar dugu. Eta, lehenik eta behin, gauza "txikiago" hori nola antolatuko duzun erabaki behar duzu.

Hiru puntu gako identifikatu ditugu:

  • nor eskaera hau bidali zuen
    Hau da, zein aplikaziotatik β€œiritsi” zen: web interfazea, backend-a, ordainketa-sistema edo beste zerbait.
  • non gertatu zen
    Zein zerbitzari zehatzetan? Aplikazio baten azpian hainbat zerbitzari badituzu eta bat-batean bat "ergelkeria" bihurtzen bada ("diskoa ustelduta dagoelako", "memoria filtratuta dagoelako", beste arazoren bat), orduan zerbitzariari berariaz zuzendu behar duzu.
  • gisa arazoa era batera edo bestera agertu zen

"Nork" bidali digun eskaera ulertzeko, tresna estandar bat erabiltzen dugu - saio-aldagai bat ezarriz: SET application_name = '{bl-host}:{bl-method}'; β€” Eskaera datorren negozio logikoaren ostalariaren izena eta hura abiarazi duen metodoaren edo aplikazioaren izena bidaltzen dugu.

Eskaeraren "jabea" pasatu ondoren, erregistrora atera behar da - horretarako aldagaia konfiguratzen dugu log_line_prefix = ' %m [%p:%v] [%d] %r %a'. Interesa dutenentzat, agian begiratu eskuliburuanzer esan nahi du horrek guztiak. Erregistroan ikusten dugu:

  • denbora
  • prozesu eta transakzio identifikatzaileak
  • datu-basearen izena
  • Eskaera hau bidali duen pertsonaren IP
  • eta metodoaren izena

PostgreSQL kontsulten optimizazioa masiboa. Kirill Borovikov (Tentsorea)

Orduan konturatu ginen ez dela oso interesgarria zerbitzari desberdinen arteko eskaera baten korrelazioa aztertzea. Ez da askotan aplikazio bat han eta hemen berdin izorratzen den egoera bat izatea. Baina berdina bada ere, begiratu zerbitzari horietako edozein.

Beraz, hona hemen mozketa "zerbitzari bat - egun bat" nahikoa iruditu zitzaigun edozein azterketa egiteko.

Lehen atal analitikoa berdina da "lagina" - Planaren aurkezpen forma laburtua, zenbakizko adierazle guztiak garbituta. Bigarren ebaketa aplikazioa edo metodoa da, eta hirugarren ebaketa, arazoak sortu dizkigun plan-nodo espezifikoa.

Instantzia zehatzetatik txantiloietara pasatu ginenean, bi abantaila lortu genituen aldi berean:

  • analisirako objektu kopuruaren murrizketa anitz
    Arazoa jada ez milaka kontsulta edo planen bidez aztertu behar dugu, dozenaka txantiloiren bidez baizik.
  • denbora-lerroa
    Hau da, atal jakin baten barruan "gertaerak" laburbilduz, egunean zehar haien itxura bistaratu dezakezu. Eta hemen ulertu ahal izango duzu eredu motaren bat gertatzen bada, adibidez, ordu batean behin, baina egunean behin gertatu beharko litzatekeela, pentsatu beharko zenuke zer gertatu den: nork eragin duen eta zergatik, agian hemen egon beharko litzateke. ez luke. Hau beste analisi metodo ez-zenbakizkoa, bisual hutsa da.

PostgreSQL kontsulten optimizazioa masiboa. Kirill Borovikov (Tentsorea)

Gainerako metodoak planetik ateratzen ditugun adierazleetan oinarritzen dira: halako eredua zenbat aldiz gertatu den, denbora osoa eta batez bestekoa, diskotik zenbat datu irakurri diren eta memoriatik zenbat...

Esaterako, ostalariaren analisi-orrira zatozelako, begira - zerbait gehiegi irakurtzen hasten da diskoan. Zerbitzariko diskoak ezin du kudeatu - nork irakurtzen du bertatik?

Eta edozein zutaberen arabera ordenatu eta oraintxe bertan zeri aurre egingo diozun erabaki dezakezu: prozesadorean edo diskoan dagoen karga, edo eskaera kopuru osoa... Ordenatu, "goieneko"-ak begiratu, konpondu eta aplikazioaren bertsio berri bat zabaldu du.
[bideo hitzaldia]

Eta berehala txantiloi berdinarekin datozen aplikazio desberdinak ikus ditzakezu bezalako eskaera batetik SELECT * FROM users WHERE login = 'Vasya'. Frontend-a, backend-a, prozesatzea... Eta galdetzen duzu zergatik irakurriko lukeen prozesatzeak erabiltzailea harekin interakzioan ez badu.

Alderantzizkoa da aplikaziotik berehala ikustea zer egiten duen. Adibidez, frontend-a hau da, hau, hau eta hau orduko behin (denbora-lerroak laguntzen du). Eta berehala sortzen da galdera: badirudi frontend-aren lana orduan behin zerbait egitea ez dela...

PostgreSQL kontsulten optimizazioa masiboa. Kirill Borovikov (Tentsorea)

Denboraren buruan, agregatua falta zitzaigula konturatu ginen plan-nodoen estatistikak. Planetatik bakartu ditugu taulen datuekin zerbait egiten duten nodoak bakarrik (indize bidez irakurri/idatzi edo ez). Izan ere, aurreko argazkiarekiko alderdi bakarra gehitzen da - zenbat erregistro ekarri dizkigu nodo honek?, eta zenbat baztertu ziren (Iragazkiak kendutako errenkadak).

Ez daukazu indize egokirik plakan, eskaera bat egiten diozu, indizetik igarotzen da, Seq Scan-era erortzen da... erregistro guztiak iragazi dituzu bat izan ezik. Zergatik behar dituzu egunean 100 milioi iragazitako erregistro? Ez al da hobe indizea igotzea?

PostgreSQL kontsulten optimizazioa masiboa. Kirill Borovikov (Tentsorea)

Plano guztiak nodoz nodo aztertuta, konturatu gara planoetan egitura tipiko batzuk daudela susmagarriak diruditenak. Eta ondo legoke garatzaileari esatea: "Lagun, hemen lehenengo indizearen arabera irakurtzen duzu, gero ordenatu eta gero moztu" - normalean, erregistro bat dago.

Kontsultak idatzi dituzten guztiek eredu hau topatu dute ziurrenik: "Eman iezadazu Vasyaren azken eskaera, bere data". Eta ez baduzu indizerik dataren arabera, edo erabili duzun indizean datarik ez badago, orduan egingo duzu. zapaldu zehatz-mehatz "rake" bera.

Baina badakigu hau "arraste" bat dela - beraz, zergatik ez esan berehala garatzaileari zer egin behar duen. Horren arabera, orain plan bat irekitzean, gure garatzaileak berehala ikusten du argazki eder bat aholkuekin, non berehala esaten zaion: "Han eta hemen arazoak dituzu, baina horrela eta horrela konpontzen dira".

Ondorioz, hasieran arazoak konpontzeko behar zen esperientzia eta orain nabarmen jaitsi da. Hau da daukagun tresna mota.

PostgreSQL kontsulten optimizazioa masiboa. Kirill Borovikov (Tentsorea)

Iturria: www.habr.com

Gehitu iruzkin berria