Učinkovito korištenje ClickHousea. Aleksej Milovidov (Yandex)

Učinkovito korištenje ClickHousea. Aleksej Milovidov (Yandex)

Budući da je ClickHouse specijalizirani sustav, pri korištenju je važno uzeti u obzir značajke njegove arhitekture. Alexey će u ovom izvješću govoriti o primjerima uobičajenih pogrešaka pri korištenju ClickHousea, koje mogu dovesti do neučinkovitog rada. Praktični primjeri pokazat će kako odabir jedne ili druge sheme obrade podataka može promijeniti izvedbu za red veličine.

Bok svima! Moje ime je Alexey, izrađujem ClickHouse.

Učinkovito korištenje ClickHousea. Aleksej Milovidov (Yandex)

Prvo, žurim vas odmah zadovoljiti, danas vam neću reći što je ClickHouse. Da budem iskren, umoran sam od toga. Svaki put ti kažem što je. I vjerojatno već svi znaju.

Učinkovito korištenje ClickHousea. Aleksej Milovidov (Yandex)

Umjesto toga, reći ću vam koje su moguće pogreške, odnosno kako možete pogrešno koristiti ClickHouse. Zapravo, nema razloga za strah, jer razvijamo ClickHouse kao sustav koji je jednostavan, praktičan i radi izvan okvira. Instalirao sam ga, nema problema.

Ali ipak morate uzeti u obzir da je ovaj sustav specijaliziran i lako možete naići na neobičan slučaj korištenja koji će ovaj sustav izbaciti iz njegove zone komfora.

Dakle, kakve grablje postoje? Uglavnom ću govoriti o očiglednim stvarima. Svima je sve jasno, svi sve razumiju i mogu biti sretni što su tako pametni, a tko ne razumije, naučit će nešto novo.

Učinkovito korištenje ClickHousea. Aleksej Milovidov (Yandex)

Prvi i najjednostavniji primjer, koji se nažalost često javlja, je veliki broj umetaka s malim serijama, odnosno veliki broj malih umetaka.

Ako uzmemo u obzir kako ClickHouse izvodi insert, tada možete poslati najmanje terabajt podataka u jednom zahtjevu. Nije problem.

I da vidimo kakva bi bila tipična izvedba. Na primjer, imamo tablicu iz podataka Yandex.Metrica. Hitovi. 105 neki stupci. 700 bajtova nekomprimiranih. I umetnut ćemo na dobar način u serijama od milijun redaka.

U tablicu umetnemo MergeTree, ispada pola milijuna redaka u sekundi. Sjajno. U repliciranoj tablici to će biti nešto manje, otprilike 400 000 redaka u sekundi.

A ako omogućite umetanje kvoruma, dobit ćete malo manje, ali još uvijek pristojne performanse, 250 termina u sekundi. Umetanje kvoruma je nedokumentirana značajka u ClickHouseu*.

* od 2020. već dokumentirano.

Učinkovito korištenje ClickHousea. Aleksej Milovidov (Yandex)

Što se događa ako učinite nešto loše? Umetnemo jedan red u tablicu MergeTree i dobijemo 59 redaka u sekundi. To je 10 000 puta sporije. U ReplicatedMergeTree – 6 redaka u sekundi. A ako je kvorum uključen, ispadaju 2 reda u sekundi. Po mom mišljenju, ovo je nekakvo apsolutno sranje. Kako možeš tako usporiti? Čak mi je na majici napisano da ClickHouse ne smije usporavati. Ali ipak se ponekad dogodi.

Učinkovito korištenje ClickHousea. Aleksej Milovidov (Yandex)

Zapravo, to je naš nedostatak. Mogli smo lako učiniti da sve dobro funkcionira, ali nismo. A nismo to učinili jer naš scenarij to nije zahtijevao. Već smo imali butcheve. Upravo smo dobili serije na našem ulazu i nema problema. Umetnemo ga i sve radi kako treba. Ali, naravno, mogući su svakakvi scenariji. Na primjer, kada imate hrpu poslužitelja na kojima se generiraju podaci. I ne ubacuju podatke tako često, ali svejedno završavaju s čestim umetanjima. A ovo moramo nekako izbjeći.

S tehničke točke gledišta, poanta je da kada napravite insert u ClickHouseu, podaci ne završe ni u jednoj memtable. Nemamo čak ni pravu log strukturu MergeTree, već samo MergeTree, jer ne postoji ni log ni memTable. Podatke jednostavno odmah zapisujemo u datotečni sustav, već raspoređene u stupce. A ako imate 100 stupaca, tada će više od 200 datoteka morati biti zapisano u poseban direktorij. Sve je ovo vrlo glomazno.

Učinkovito korištenje ClickHousea. Aleksej Milovidov (Yandex)

I postavlja se pitanje: "Kako to učiniti ispravno?" Ako je situacija takva da ipak morate nekako zabilježiti podatke u ClickHouse.

Metoda 1. Ovo je najlakši način. Koristite neku vrstu distribuiranog reda čekanja. Na primjer, Kafka. Jednostavno izvlačite podatke iz Kafke i grupirate ih jednom u sekundi. I sve će biti u redu, snimaš, sve radi kako treba.

Nedostaci su to što je Kafka još jedan glomazan distribuirani sustav. Razumijem i ako već imate Kafku u svom društvu. Dobro je, zgodno je. Ali ako ne postoji, onda biste trebali tri puta razmisliti prije nego što u svoj projekt uvučete još jedan distribuirani sustav. Stoga je vrijedno razmotriti alternative.

Učinkovito korištenje ClickHousea. Aleksej Milovidov (Yandex)

Metoda 2. Ovo je alternativa stare škole, au isto vrijeme vrlo jednostavna. Imate li neku vrstu poslužitelja koji generira vaše zapise. I samo zapisuje vaše zapisnike u datoteku. I jednom u sekundi, na primjer, preimenujemo ovu datoteku i otkinemo novu. A zasebna skripta, bilo putem crona ili nekog demona, uzima najstariju datoteku i zapisuje je u ClickHouse. Ako snimate zapise jednom u sekundi, sve će biti u redu.

Ali nedostatak ove metode je da ako vaš poslužitelj na kojem se generiraju dnevnici negdje nestane, tada će nestati i podaci.

Učinkovito korištenje ClickHousea. Aleksej Milovidov (Yandex)

Metoda 3. Postoji još jedna zanimljiva metoda, koja uopće ne zahtijeva privremene datoteke. Na primjer, imate nekakav reklamni spinner ili neki drugi zanimljiv demon koji generira podatke. I možete akumulirati hrpu podataka izravno u RAM-u, u međuspremniku. A kada prođe dovoljno vremena, ovaj međuspremnik odložite, napravite novi i u posebnoj temi ubacite ono što se već skupilo u ClickHouse.

S druge strane, podaci također nestaju s kill -9. Ako se vaš poslužitelj sruši, izgubit ćete ove podatke. A još jedan problem je da ako niste mogli pisati u bazu podataka, vaši će se podaci akumulirati u RAM-u. I ili će RAM-a nestati ili ćete jednostavno izgubiti podatke.

Učinkovito korištenje ClickHousea. Aleksej Milovidov (Yandex)

Metoda 4. Još jedna zanimljiva metoda. Imate li neki serverski proces. I može odmah poslati podatke u ClickHouse, ali učiniti to u jednoj vezi. Na primjer, poslao sam http zahtjev s transfer-encoding: chunked with insert. I generira dijelove ne previše rijetko, možete poslati svaki redak, iako će biti dodatnih troškova za uokvirivanje ovih podataka.

Međutim, u ovom slučaju podaci će odmah biti poslani u ClickHouse. A ClickHouse će ih sam pohraniti.

Ali javljaju se i problemi. Sada ćete izgubiti podatke, uključujući kada se vaš proces prekine i ako se ClickHouse proces prekine, jer će to biti nepotpuni umetak. A u ClickHouseu umetci su atomski do određenog određenog praga u veličini redaka. U principu, ovo je zanimljiv način. Također se može koristiti.

Učinkovito korištenje ClickHousea. Aleksej Milovidov (Yandex)

Metoda 5. Evo još jedne zanimljive metode. Ovo je neka vrsta poslužitelja koji je razvila zajednica za grupiranje podataka. Nisam ga osobno gledao pa ne mogu ništa garantirati. Međutim, za sam ClickHouse ne postoje nikakva jamstva. Ovo je također otvorenog koda, ali s druge strane, možda ste navikli na neki standard kvalitete koji pokušavamo pružiti. Ali za ovu stvar - ne znam, idite na GitHub, pogledajte kod. Možda su napisali nešto normalno.

* od 2020. također treba dodati u obzir KittenHouse.

Učinkovito korištenje ClickHousea. Aleksej Milovidov (Yandex)

Metoda 6. Druga metoda je korištenje tablica međuspremnika. Prednost ove metode je što ju je vrlo lako početi koristiti. Napravite Buffer tablicu i umetnite je u nju.

Nedostatak je što problem nije u potpunosti riješen. Ako, u brzini kao što je MergeTree, morate grupirati podatke prema jednoj seriji u sekundi, tada u brzini u međuspremničkoj tablici morate grupirati barem do nekoliko tisuća u sekundi. Ako je više od 10 u sekundi, to će i dalje biti loše. A ako ga umetnete u serijama, onda ste vidjeli da ispada sto tisuća redaka u sekundi. I to je već na prilično velikim podacima.

Također međuspremničke tablice nemaju dnevnik. A ako nešto nije u redu s vašim poslužiteljem, podaci će biti izgubljeni.

Učinkovito korištenje ClickHousea. Aleksej Milovidov (Yandex)

I kao bonus, nedavno smo dobili priliku u ClickHouseu dohvatiti podatke iz Kafke. Postoji stolni motor - Kafka. Vi samo stvarate. I na njega možete objesiti materijalizirane prikaze. U tom će slučaju sam izvući podatke iz Kafke i umetnuti ih u tablice koje su vam potrebne.

A ono što posebno veseli u ovoj prilici je da to nismo učinili mi. Ovo je značajka zajednice. A kad kažem "značajka zajednice", mislim to bez imalo prijezira. Pročitali smo kôd, pregledali, trebao bi dobro funkcionirati.

* od 2020. pojavila se slična podrška za Zec MQ.

Učinkovito korištenje ClickHousea. Aleksej Milovidov (Yandex)

Što bi još moglo biti nezgodno ili neočekivano prilikom umetanja podataka? Ako napravite zahtjev za umetanje vrijednosti i napišete neke izračunate izraze u vrijednostima. Na primjer, now() je također izračunati izraz. I u ovom slučaju, ClickHouse je prisiljen pokrenuti tumač ovih izraza na svakom retku, a izvedba će pasti za redove veličine. Bolje je izbjegavati ovo.

* trenutno je problem u potpunosti riješen, više nema regresije performansi pri korištenju izraza u VRIJEDNOSTIMA.

Drugi primjer je kada može doći do nekih problema kada imate podatke o jednoj seriji koja pripada hrpi particija. Prema zadanim postavkama, ClickHouse particije su po mjesecima. A ako umetnete seriju od milijun redaka, a postoje podaci za nekoliko godina, tada ćete tamo imati nekoliko desetaka particija. A to je jednako činjenici da će postojati serije nekoliko desetaka puta manje veličine, jer su iznutra uvijek prvo podijeljene na particije.

* Nedavno je ClickHouse u eksperimentalnom načinu rada dodao podršku za kompaktni format chunkova i chunkova u RAM-u s zapisom unaprijed, što gotovo u potpunosti rješava problem.

Učinkovito korištenje ClickHousea. Aleksej Milovidov (Yandex)

Sada pogledajmo drugu vrstu problema - upisivanje podataka.

Upisivanje podataka može biti striktno ili string. String je kada ste ga samo uzeli i izjavili da su sva vaša polja tipa string. Ovo je sranje. Nema potrebe za ovim.

Idemo smisliti kako to ispravno napraviti u onim slučajevima kada želite reći da imamo neko polje, string, i neka ClickHouse to sam shvati, a ja se neću truditi. Ali ipak se isplati potruditi.

Učinkovito korištenje ClickHousea. Aleksej Milovidov (Yandex)

Na primjer, imamo IP adresu. U jednom smo ga slučaju spremili kao niz. Na primjer, 192.168.1.1. A u drugom slučaju, to će biti broj tipa UInt32*. 32 bita je dovoljno za IPv4 adresu.

Prvo, što je čudno, podaci će biti komprimirani približno jednako. Bit će razlika, naravno, ali ne toliko velika. Dakle, nema posebnih problema s I/O diska.

Ali postoji ozbiljna razlika u vremenu procesora i vremenu izvršenja upita.

Izbrojimo broj jedinstvenih IP adresa ako su pohranjene kao brojevi. To je 137 milijuna linija u sekundi. Ako je isti u obliku nizova, onda 37 milijuna linija u sekundi. Ne znam zašto je došlo do ove slučajnosti. Sam sam izvršio te zahtjeve. Ali još uvijek oko 4 puta sporije.

A ako izračunate razliku u prostoru na disku, onda također postoji razlika. A razlika je otprilike jedna četvrtina, jer ima dosta jedinstvenih IP adresa. A kad bi postojali stihovi s malim brojem različitih značenja, onda bi se lako sabili prema rječniku u približno isti volumen.

A četverostruka vremenska razlika ne leži na cesti. Možda ti je, naravno, svejedno, ali kad vidim toliku razliku, bude mi tužno.

Učinkovito korištenje ClickHousea. Aleksej Milovidov (Yandex)

Pogledajmo različite slučajeve.

1. Jedan slučaj kada imate nekoliko različitih jedinstvenih vrijednosti. U ovom slučaju koristimo jednostavnu praksu koju vjerojatno znate i koju možete koristiti za bilo koji DBMS. Sve ovo ima smisla ne samo za ClickHouse. Samo upišite numeričke identifikatore u bazu podataka. A možete pretvoriti u nizove i natrag na strani aplikacije.

Na primjer, imate regiju. A vi ga pokušavate spremiti kao niz. I tamo će pisati: Moskva i Moskovska oblast. I kad vidim da piše “Moskva”, nije ništa, ali kad je Moskva, nekako mi bude skroz tužno. Ovo je koliko bajtova.

Umjesto toga, jednostavno zapišemo broj Ulnt32 i 250. Imamo 250 u Yandexu, ali vaš može biti drugačiji. Za svaki slučaj, reći ću da ClickHouse ima ugrađenu mogućnost rada s geobazom. Jednostavno zapišete direktorij s regijama, uključujući i hijerarhijski, tj. bit će Moskva, Moskovska regija i sve što vam treba. I možete pretvoriti na razini zahtjeva.

Učinkovito korištenje ClickHousea. Aleksej Milovidov (Yandex)

Druga opcija je približno ista, ali s podrškom unutar ClickHousea. Ovo je tip podataka Enum. Jednostavno napišete sve vrijednosti koje su vam potrebne unutar Enuma. Na primjer, tip uređaja i tamo napišite: desktop, mobile, tablet, TV. Ukupno postoje 4 opcije.

Nedostatak je što ga morate povremeno mijenjati. Dodana je samo jedna opcija. Promijenimo tablicu. Zapravo, alter table u ClickHouseu je besplatan. Posebno besplatno za Enum jer se podaci na disku ne mijenjaju. No unatoč tome, alter dobiva zaključavanje* na stolu i mora čekati dok se ne izvrše svi odabiri. I tek nakon što se ova izmjena izvrši, tj. još uvijek postoje neke neugodnosti.

* u najnovijim verzijama ClickHousea, ALTER je napravljen potpuno neblokiran.

Učinkovito korištenje ClickHousea. Aleksej Milovidov (Yandex)

Još jedna opcija koja je prilično jedinstvena za ClickHouse je povezivanje vanjskih rječnika. Možete pisati brojeve u ClickHouse i držati svoje imenike u bilo kojem sustavu koji vam odgovara. Na primjer, možete koristiti: MySQL, Mongo, Postgres. Možete čak i izraditi vlastiti mikroservis koji će te podatke slati putem http-a. A na razini ClickHousea napišete funkciju koja će ove podatke pretvoriti iz brojeva u nizove.

Ovo je specijaliziran, ali vrlo učinkovit način za izvođenje spajanja na vanjskoj tablici. I postoje dvije opcije. U jednoj izvedbi, ovi će podaci biti potpuno predmemorirani, potpuno prisutni u RAM-u i ažurirani s određenom učestalošću. A u drugoj opciji, ako ti podaci ne stanu u RAM, možete ih djelomično predmemorirati.

Evo primjera. Postoji Yandex.Direct. A tu je i reklamna tvrtka i banneri. Vjerojatno postoje deseci milijuna tvrtki za oglašavanje. I otprilike stanu u RAM. A postoje milijarde bannera, ne stanu. I koristimo predmemorirani rječnik iz MySQL-a.

Jedini je problem što će predmemorirani rječnik dobro funkcionirati ako je stopa pogodaka blizu 100%. Ako je manji, tada ćete prilikom obrade upita za svaku skupinu podataka zapravo morati uzeti ključeve koji nedostaju i otići uzeti podatke iz MySQL-a. Što se tiče ClickHousea, to još uvijek mogu jamčiti - da, ne usporava, neću govoriti o drugim sustavima.

A kao bonus, rječnici su vrlo jednostavan način za retroaktivno ažuriranje podataka u ClickHouseu. Odnosno, imali ste izvješće o oglašivačkim tvrtkama, korisnik je jednostavno promijenio oglašivačku tvrtku i u svim starim podacima, u svim izvješćima, i ti su se podaci promijenili. Ako retke pišete izravno u tablicu, bit će ih nemoguće ažurirati.

Učinkovito korištenje ClickHousea. Aleksej Milovidov (Yandex)

Još jedan način kada ne znate gdje nabaviti identifikatore za nizove. možete jednostavno raspršiti. Štoviše, najjednostavnija opcija je uzeti 64-bitni hash.

Jedini je problem što ako je hash 64-bitni, tada ćete gotovo sigurno imati kolizije. Jer ako tamo ima milijardu redaka, tada vjerojatnost već postaje primjetna.

I ne bi bilo dobro da se imena reklamnih tvrtki zbrinjavaju na ovaj način. Ako se reklamne kampanje različitih tvrtki miješaju, tada će biti nešto neshvatljivo.

A postoji i jednostavan trik. Istina, nije baš prikladan za ozbiljne podatke, ali ako nešto nije jako ozbiljno, onda samo dodajte identifikator klijenta ključu rječnika. I tada ćete imati kolizije, ali samo unutar jednog klijenta. Ovu metodu koristimo za mape veza u Yandex.Metrici. Tamo imamo URL-ove, pohranjujemo hashove. I znamo da, naravno, postoje kolizije. Ali kada se stranica prikaže, može se zanemariti vjerojatnost da su na jednoj stranici jednog korisnika neki URL-ovi zalijepljeni i da će se to primijetiti.

Kao bonus, za mnoge operacije dovoljni su sami hashovi, a sami nizovi ne moraju se nigdje pohranjivati.

Učinkovito korištenje ClickHousea. Aleksej Milovidov (Yandex)

Drugi primjer je ako su nizovi kratki, na primjer, domene web stranica. Mogu se pohraniti takvi kakvi jesu. Ili, na primjer, jezik preglednika ru – 2 bajta. Naravno, stvarno mi je žao bajtova, ali ne brinite, 2 bajta nisu šteta. Molimo vas da ostane takvim, ne brinite.

Učinkovito korištenje ClickHousea. Aleksej Milovidov (Yandex)

Drugi je slučaj kada, naprotiv, ima puno linija i u njima ima puno jedinstvenih, a čak je i skup potencijalno neograničen. Tipičan primjer su izrazi za pretraživanje ili URL-ovi. Fraze za pretraživanje, uključujući pogreške pri upisu. Pogledajmo koliko ima jedinstvenih izraza za pretraživanje po danu. I ispada da su oni gotovo polovica svih događaja. I u ovom slučaju, mogli biste pomisliti da trebate normalizirati podatke, prebrojati identifikatore i staviti ih u zasebnu tablicu. Ali ne trebate to učiniti. Samo ostavite ove retke onakvima kakvi jesu.

Bolje je ne izmišljati ništa, jer ako ga pohranite odvojeno, morat ćete napraviti spajanje. A ovo spajanje je, u najboljem slučaju, slučajni pristup memoriji, ako još stane u memoriju. Ako ne odgovara, bit će problema.

A ako su podaci pohranjeni na mjestu, onda se jednostavno čitaju potrebnim redoslijedom iz datotečnog sustava i sve je u redu.

Učinkovito korištenje ClickHousea. Aleksej Milovidov (Yandex)

Ako imate URL-ove ili neki drugi složeni dugi niz, vrijedi razmisliti o tome da možete unaprijed izračunati neku vrstu ekstrakta i napisati ga u zasebnom stupcu.

Za URL-ove, na primjer, možete zasebno pohraniti domenu. A ako stvarno trebate domenu, onda samo upotrijebite ovaj stupac i URL-ovi će ležati tamo, a vi ih nećete ni dirati.

Da vidimo koja je razlika. ClickHouse ima specijaliziranu funkciju koja izračunava domenu. Vrlo je brz, mi smo ga optimizirali. I, da budemo iskreni, nije čak ni u skladu s RFC-om, ali ipak uzima u obzir sve što nam treba.

A u jednom slučaju jednostavno ćemo dobiti URL-ove i izračunati domenu. To je 166 milisekundi. A ako uzmete gotovu domenu, ispada da je samo 67 milisekundi, odnosno gotovo tri puta brže. I brži je ne zato što moramo raditi neke izračune, već zato što čitamo manje podataka.

Zato jedan zahtjev, koji je sporiji, ima veću brzinu od gigabajta u sekundi. Jer čita više gigabajta. Ovo su potpuno nepotrebni podaci. Čini se da se zahtjev izvodi brže, ali mu je potrebno više vremena da se izvrši.

A ako pogledate količinu podataka na disku, ispada da je URL 126 megabajta, a domena samo 5 megabajta. Ispada 25 puta manje. Ali unatoč tome, zahtjev se izvršava samo 4 puta brže. Ali to je zato što su podaci vrući. A da je hladno, vjerojatno bi bio 25 puta brži zbog disk I/O.

Usput, ako procijenite koliko je domena manja od URL-a, ispada da je oko 4 puta manja, ali iz nekog razloga podaci na disku zauzimaju 25 puta manje. Zašto? Zbog kompresije. I URL je komprimiran, i domena je komprimirana. Ali često URL sadrži hrpu smeća.

Učinkovito korištenje ClickHousea. Aleksej Milovidov (Yandex)

I, naravno, isplati se koristiti prave tipove podataka koji su dizajnirani posebno za željene vrijednosti ili koji su prikladni. Ako ste u IPv4, pohranite UInt32*. Ako je IPv6, tada FixedString(16), jer je IPv6 adresa 128 bita, tj. pohranjena izravno u binarnom formatu.

Ali što ako ponekad imate IPv4 adrese, a ponekad IPv6? Da, možete pohraniti oboje. Jedan stupac za IPv4, drugi za IPv6. Naravno, postoji opcija za prikaz IPv4 u IPv6. Ovo će također raditi, ali ako često trebate IPv4 adresu u zahtjevima, bilo bi lijepo staviti je u zasebnu kolonu.

* ClickHouse sada ima zasebne IPv4, IPv6 tipove podataka koji pohranjuju podatke jednako učinkovito kao i brojevi, ali ih predstavljaju prikladno kao nizove.

Učinkovito korištenje ClickHousea. Aleksej Milovidov (Yandex)

Također je važno napomenuti da je vrijedno prethodno obraditi podatke. Na primjer, dobivate neobrađene zapise. I možda ih ne biste trebali odmah staviti u ClickHouse, iako je vrlo primamljivo ne raditi ništa i sve će raditi. Ali još uvijek vrijedi izvršiti moguće izračune.

Na primjer, verzija preglednika. U nekom obližnjem odjelu, u koji ne želim uprijeti prstom, verzija preglednika je pohranjena ovako, odnosno kao niz: 12.3. I onda, da bi napravili izvješće, uzmu ovaj niz i dijele ga na niz, a zatim na prvi element niza. Naravno, sve se usporava. Pitao sam zašto to rade. Rekli su mi da ne vole preuranjenu optimizaciju. I ne volim preuranjenu pesimizaciju.

Dakle, u ovom slučaju bilo bi ispravnije podijeliti u 4 stupca. Ovdje se nemojte bojati, jer ovo je ClickHouse. ClickHouse je stupčasta baza podataka. I što više urednih malih stupaca, to bolje. Bit će 5 verzija preglednika, napravite 5 stupaca. Ovo je u redu.

Učinkovito korištenje ClickHousea. Aleksej Milovidov (Yandex)

Sada pogledajmo što učiniti ako imate mnogo vrlo dugih nizova, vrlo dugih nizova. Uopće ih nije potrebno pohraniti u ClickHouse. Umjesto toga, identifikator možete pohraniti samo u ClickHouse. I staviti ove duge redove u neki drugi sustav.

Na primjer, jedna od naših analitičkih usluga ima neke parametre događaja. A ako ima mnogo parametara za događaje, jednostavno spremimo prvih 512 koji naiđu. Jer 512 nije šteta.

Učinkovito korištenje ClickHousea. Aleksej Milovidov (Yandex)

A ako se ne možete odlučiti za svoje tipove podataka, onda podatke možete bilježiti i u ClickHouseu, ali u privremenu tablicu tipa Log, posebnu za privremene podatke. Nakon toga možete analizirati kakvu raspodjelu vrijednosti tamo imate, što je tamo općenito i stvoriti ispravne tipove.

*ClickHouse sada ima tip podataka Niska kardinalnost što vam omogućuje učinkovito pohranjivanje nizova uz manje napora.

Učinkovito korištenje ClickHousea. Aleksej Milovidov (Yandex)

Sada pogledajmo još jedan zanimljiv slučaj. Ponekad stvari rade čudno za ljude. Uđem i vidim ovo. I odmah se čini da je to napravio neki vrlo iskusan, pametan admin koji ima veliko iskustvo u postavljanju MySQL verzije 3.23.

Ovdje vidimo tisuću tablica od kojih svaka bilježi ostatak dijeljenja tko zna čega s tisuću.

U principu, poštujem tuđe iskustvo, uključujući i razumijevanje patnje koja se tim iskustvom može steći.

Učinkovito korištenje ClickHousea. Aleksej Milovidov (Yandex)

A razlozi su više-manje jasni. To su stari stereotipi koji su se možda nakupili tijekom rada s drugim sustavima. Na primjer, MyISAM tablice nemaju klasterirani primarni ključ. A ovaj način dijeljenja podataka može biti očajnički pokušaj da se dobije ista funkcionalnost.

Drugi razlog je taj što je teško izvršiti bilo kakve operacije mijenjanja na velikim tablicama. Sve će biti blokirano. Iako u modernim verzijama MySQL-a ovaj problem više nije tako ozbiljan.

Ili, na primjer, microsharding, ali o tome kasnije.

Učinkovito korištenje ClickHousea. Aleksej Milovidov (Yandex)

Nema potrebe to raditi u ClickHouseu, jer je, prvo, primarni ključ grupiran, podaci su poredani po primarnom ključu.

Ponekad me ljudi pitaju: "Kako se izvedba upita raspona u ClickHouseu razlikuje ovisno o veličini tablice?" Ja kažem da se uopće ne mijenja. Na primjer, imate tablicu s milijardu redaka i čitate raspon od milijun redaka. Sve je u redu. Ako u tablici postoji trilijun redaka, a vi pročitate milijun redaka, bit će gotovo isto.

I, drugo, nisu potrebne sve vrste stvari poput ručnih particija. Ako uđete i pogledate što se nalazi u datotečnom sustavu, vidjet ćete da je tablica prilično velika stvar. A unutra je nešto poput pregrada. Odnosno, ClickHouse radi sve za vas i ne morate patiti.

Učinkovito korištenje ClickHousea. Aleksej Milovidov (Yandex)

Alter u ClickHouseu je besplatan ako promijenite stupac za dodavanje/ispuštanje.

I ne biste trebali praviti male tablice, jer ako imate 10 redaka ili 10 000 redaka u tablici, onda to uopće nije važno. ClickHouse je sustav koji optimizira propusnost, a ne latenciju, tako da nema smisla obrađivati ​​10 linija.

Učinkovito korištenje ClickHousea. Aleksej Milovidov (Yandex)

Ispravno je koristiti jednu veliku tablicu. Oslobodite se starih stereotipa, sve će biti u redu.

I kao bonus, u najnovijoj verziji sada imamo mogućnost kreiranja proizvoljnog particionog ključa kako bismo izvršili sve vrste operacija održavanja na pojedinačnim particijama.

Na primjer, potrebno vam je mnogo malih tablica, na primjer, kada postoji potreba za obradom nekih međupodataka, dobijete dijelove i trebate izvršiti transformaciju na njima prije nego što upišete konačnu tablicu. Za ovaj slučaj postoji prekrasan stolni motor - StripeLog. To je kao TinyLog, samo bolji.

* sada ima i ClickHouse unos funkcije tablice.

Učinkovito korištenje ClickHousea. Aleksej Milovidov (Yandex)

Drugi antiuzorak je mikrosharding. Na primjer, trebate shardirati podatke i imate 5 poslužitelja, a sutra će biti 6 poslužitelja. I razmišljate o tome kako ponovno uravnotežiti ove podatke. Umjesto toga, ne razbijate se na 5 krhotina, već na 1 krhotina. I onda mapirate svaki od tih microshardova na zasebni poslužitelj. I dobit ćete npr. 000 ClickHousesa na jednom serveru npr. Odvojene instance na zasebnim portovima ili zasebnim bazama podataka.

Učinkovito korištenje ClickHousea. Aleksej Milovidov (Yandex)

Ali to nije baš dobro u ClickHouseu. Jer čak i jedna ClickHouse instanca pokušava iskoristiti sve dostupne resurse poslužitelja za obradu jednog zahtjeva. Odnosno, imate nekakav server i on ima npr. 56 procesorskih jezgri. Pokrećete upit za koji je potrebna jedna sekunda i koristit će 56 jezgri. A ako tamo postavite 200 ClickHousesa na jedan poslužitelj, ispada da će se pokrenuti 10 niti. Općenito, sve će biti vrlo loše.

Drugi razlog je taj što će raspodjela posla među tim instancama biti neravnomjerna. Neki će završiti ranije, neki kasnije. Kad bi se sve to dogodilo u jednom slučaju, ClickHouse bi sam smislio kako pravilno distribuirati podatke među nitima.

A drugi razlog je taj što ćete imati međuprocesorsku komunikaciju putem TCP-a. Podatke će trebati serijalizirati, deserijalizirati, a to je ogroman broj microsharda. Jednostavno neće djelovati učinkovito.

Učinkovito korištenje ClickHousea. Aleksej Milovidov (Yandex)

Još jedan antiuzor, iako se teško može nazvati antiuzorkom. Ovo je velika količina predagregacije.

Općenito, predagregacija je dobra. Imali ste milijardu redaka, agregirali ste to i postalo je 1 redaka, a sada se upit izvršava trenutno. Sve je odlično. Možeš ti to. A za to, čak i ClickHouse ima posebnu vrstu tablice, AggregatingMergeTree, koja izvodi inkrementalnu agregaciju kako se podaci ubacuju.

Ali postoje trenuci kada mislite da ćemo prikupljati podatke poput ovoga i prikupljati podatke poput ovoga. A u nekom susjednom odjelu, također ne želim reći kojem, koriste SummingMergeTree tablice za sumiranje po primarnom ključu, a kao primarni ključ koristi se 20-ak stupaca. Za svaki slučaj, promijenio sam nazive nekih stupaca zbog tajnosti, ali to je uglavnom to.

Učinkovito korištenje ClickHousea. Aleksej Milovidov (Yandex)

I takvi problemi nastaju. Prvo, količina vaših podataka ne smanjuje se previše. Na primjer, smanjuje se za tri puta. Tri puta bi bila dobra cijena da si priuštite neograničene analitičke mogućnosti koje nastaju ako vaši podaci nisu agregirani. Ako su podaci agregirani, onda umjesto analitike dobijete samo jadnu statistiku.

I što je tu tako posebno? Činjenica je da ti ljudi iz susjednog odjela ponekad odu i zatraže da primarnom ključu dodaju još jednu kolonu. Odnosno, ovako smo agregirali podatke, ali sada želimo malo više. Ali ClickHouse nema alter primarni ključ. Stoga moramo napisati neke skripte u C++. I ne volim skripte, čak i ako su u C++.

A ako pogledate za što je ClickHouse stvoren, onda su neagregirani podaci upravo scenarij za koji su rođeni. Ako koristite ClickHouse za neagregirane podatke, onda to radite kako treba. Ako agregirate, to je ponekad oprostivo.

Učinkovito korištenje ClickHousea. Aleksej Milovidov (Yandex)

Još jedan zanimljiv slučaj su upiti u beskonačnoj petlji. Ponekad odem na neki produkcijski poslužitelj i tamo pogledam show processlist. I svaki put otkrijem da se događa nešto strašno.

Na primjer, ovako. Odmah je jasno da se sve može napraviti u jednom zahtjevu. Samo upišite url i popis tamo.

Učinkovito korištenje ClickHousea. Aleksej Milovidov (Yandex)

Zašto su mnogi takvi upiti u beskonačnoj petlji loši? Ako se indeks ne koristi, imat ćete mnogo prolazaka preko istih podataka. Ali ako se koristi indeks, na primjer, imate primarni ključ za ru i tamo pišete url = nešto. I misliš ako se samo jedan URL pročita iz tablice, sve će biti u redu. Ali zapravo ne. Jer ClickHouse sve radi u serijama.

Kad treba pročitati određeni raspon podataka, čita malo više, jer je indeks u ClickHouseu oskudan. Ovaj vam indeks ne dopušta da pronađete pojedinačni redak u tablici, već samo neku vrstu raspona. A podaci su komprimirani u blokove. Da biste pročitali jedan red, morate uzeti cijeli blok i otpustiti ga. A ako pokrećete hrpu upita, imat ćete puno preklapanja i morat ćete puno posla raditi iznova i iznova.

Učinkovito korištenje ClickHousea. Aleksej Milovidov (Yandex)

I kao bonus, možete primijetiti da se u ClickHouseu ne biste trebali bojati prenijeti čak ni megabajte, pa čak ni stotine megabajta u odjeljak IN. Sjećam se iz naše prakse da ako u MySQL-u prenesemo hrpu vrijednosti u odjeljak IN, na primjer, tamo prenesemo 100 megabajta nekih brojeva, onda MySQL pojede 10 gigabajta memorije i ništa mu se više ne događa, sve radi slabo.

A drugo je da u ClickHouseu, ako vaši upiti koriste indeks, to uvijek nije sporije od potpunog skeniranja, tj. ako trebate pročitati gotovo cijelu tablicu, ići će sekvencijalno i pročitati cijelu tablicu. Općenito, on će to sam shvatiti.

Ali ipak postoje neke poteškoće. Na primjer, činjenica da IN s podupitom ne koristi indeks. Ali to je naš problem i moramo ga riješiti. Nema tu ničeg temeljnog. Popravit ćemo to*.

I još jedna zanimljiva stvar je da ako imate jako dugačak zahtjev i distribuirana obrada zahtjeva je u tijeku, onda će taj vrlo dugačak zahtjev biti poslan svakom poslužitelju bez kompresije. Na primjer, 100 megabajta i 500 poslužitelja. I, sukladno tome, imat ćete 50 gigabajta prenesenih preko mreže. Bit će preneseno i tada će sve biti uspješno završeno.

* već koristim; Sve je popravljeno kao što je obećano.

Učinkovito korištenje ClickHousea. Aleksej Milovidov (Yandex)

A prilično čest slučaj je kada zahtjevi dolaze iz API-ja. Na primjer, stvorili ste neku vrstu vlastite usluge. A ako netko treba vašu uslugu, onda otvorite API i doslovno nakon dva dana vidite da se događa nešto neshvatljivo. Sve je preopterećeno i stižu neki strašni zahtjevi koji se nisu smjeli dogoditi.

A rješenje je samo jedno. Ako ste otvorili API, morat ćete ga rezati. Recimo, uvesti nekakve kvote. Nema drugih normalnih opcija. Inače će odmah napisati scenarij i bit će problema.

A ClickHouse ima i posebnost – izračun kvota. Štoviše, možete prenijeti svoj ključ kvote. To je, na primjer, interni korisnički ID. A kvote će se izračunavati neovisno za svaku od njih.

Učinkovito korištenje ClickHousea. Aleksej Milovidov (Yandex)

Sada još jedna zanimljivost. Ovo je ručna replikacija.

Znam za mnoge slučajeve u kojima, unatoč tome što ClickHouse ima ugrađenu podršku za replikaciju, ljudi ručno repliciraju ClickHouse.

Koji je princip? Imate cjevovod za obradu podataka. I radi neovisno, na primjer, u različitim podatkovnim centrima. Iste podatke na isti način upisujete u ClickHouse. Istina, praksa pokazuje da će podaci ipak odstupati zbog nekih značajki u vašem kodu. Nadam se da je u tvojoj.

S vremena na vrijeme ipak ćete morati ručno sinkronizirati. Na primjer, jednom mjesečno administratori rade rsync.

Zapravo, puno je lakše koristiti replikaciju ugrađenu u ClickHouse. Ali mogu postojati neke kontraindikacije, jer za ovo morate koristiti ZooKeeper. Neću reći ništa loše o ZooKeeperu, u principu, sustav radi, ali se događa da ga ljudi ne koriste zbog java-fobije, jer ClickHouse je tako dobar sustav, napisan u C++, koji možete koristiti i sve će biti dobro . A ZooKeeper je u Javi. I nekako ne želite ni pogledati, ali onda možete koristiti ručnu replikaciju.

Učinkovito korištenje ClickHousea. Aleksej Milovidov (Yandex)

ClickHouse je praktičan sustav. Ona uzima u obzir vaše potrebe. Ako imate ručnu replikaciju, tada možete stvoriti Distribuiranu tablicu koja pregledava vaše ručne replike i vrši failover između njih. A postoji čak i posebna opcija koja vam omogućuje da izbjegnete neuspjehe, čak i ako se vaše linije sustavno razlikuju.

Učinkovito korištenje ClickHousea. Aleksej Milovidov (Yandex)

Daljnji problemi mogu nastati ako koristite primitivne tablične strojeve. ClickHouse je konstruktor koji ima hrpu različitih pokretača stolova. Za sve ozbiljne slučajeve, kako piše u dokumentaciji, koristite tablice iz MergeTree obitelji. A sve ostalo - to je tako, za pojedinačne slučajeve ili za testove.

U tablici MergeTree ne morate imati nikakav datum i vrijeme. Još uvijek ga možete koristiti. Ako nema datuma i vremena, napišite da je zadana vrijednost 2000. Ovo će funkcionirati i neće zahtijevati resurse.

A u novoj verziji poslužitelja možete čak odrediti da imate prilagođeno particioniranje bez ključa particije. Bit će isto.

Učinkovito korištenje ClickHousea. Aleksej Milovidov (Yandex)

S druge strane, možete koristiti primitivne tablične strojeve. Na primjer, jednom unesite podatke i pogledajte, okrećite i izbrišite. Možete koristiti Log.

Ili pohranjivanje malih količina za srednju obradu je StripeLog ili TinyLog.

Memorija se može koristiti ako je količina podataka mala i možete jednostavno prevrtati nešto u RAM-u.

Učinkovito korištenje ClickHousea. Aleksej Milovidov (Yandex)

ClickHouse baš i ne voli renormalizirane podatke.

Evo tipičnog primjera. Ovo je ogroman broj URL-ova. Stavite ih u sljedeću tablicu. I onda su odlučili napraviti JOIN s njima, ali to u pravilu neće raditi jer ClickHouse podržava samo Hash JOIN. Ako nema dovoljno RAM-a za puno podataka koje je potrebno povezati, JOIN neće raditi*.

Ako su podaci visoke kardinalnosti, ne brinite, pohranite ih u denormaliziranom obliku, URL-ovi su izravno na mjestu u glavnoj tablici.

* a sada ClickHouse ima i merge join, a radi u uvjetima kada međupodaci ne stanu u RAM. Ali to je neučinkovito i preporuka ostaje na snazi.

Učinkovito korištenje ClickHousea. Aleksej Milovidov (Yandex)

Još par primjera, ali već sumnjam jesu li antišabloni ili ne.

ClickHouse ima jednu poznatu manu. Ne zna ažurirati*. Na neki način, ovo je čak i dobro. Ako imate neke važne podatke, na primjer, računovodstvo, tada ih nitko neće moći poslati jer nema ažuriranja.

* podrška za ažuriranje i brisanje u skupnom načinu dodana je prije mnogo vremena.

Ali postoje neki posebni načini koji omogućuju ažuriranje kao u pozadini. Na primjer, tablice poput ReplaceMergeTree. Ažuriraju se tijekom spajanja u pozadini. To možete forsirati pomoću optimizirane tablice. Ali nemojte to činiti prečesto, jer će u potpunosti prebrisati particiju.

Planer upita također loše obrađuje distribuirane JOIN-ove u ClickHouseu.

Loše, ali ponekad OK.

Upotreba ClickHousea samo za čitanje podataka pomoću select*.

Ne bih preporučio korištenje ClickHousea za glomazne izračune. Ali to nije sasvim točno, jer se već udaljavamo od ove preporuke. A nedavno smo dodali mogućnost primjene modela strojnog učenja u ClickHouse - Catboost. I smeta me jer pomislim: “Kakav užas. Evo koliko ciklusa po bajtu ispada! Stvarno mrzim gubiti satove na bajtove.

Učinkovito korištenje ClickHousea. Aleksej Milovidov (Yandex)

Ali ne bojte se, instalirajte ClickHouse, sve će biti u redu. Ako išta, imamo zajednicu. Usput, zajednica ste vi. A ako imate problema, možete barem otići na naš chat, i nadamo se da će vam pomoći.

pitanja

Hvala na izvješću! Gdje se mogu žaliti na pad ClickHousea?

Možete se odmah žaliti meni osobno.

Nedavno sam počeo koristiti ClickHouse. Odmah sam izbacio cli sučelje.

Kakav rezultat.

Malo kasnije srušio sam server malim odabirom.

Ti imaš talenta.

Otvorio sam GitHub bug, ali je zanemaren.

Vidjet ćemo.

Alexey me prevario da prisustvujem izvješću, obećavši mi da će mi reći kako pristupaš podacima unutra.

Vrlo jednostavno.

Jučer sam to shvatio. Više specifičnosti.

Nema tu strašnih trikova. Postoji samo kompresija blok po blok. Zadana vrijednost je LZ4, možete omogućiti ZSTD*. Blokovi od 64 kilobajta do 1 megabajta.

* postoji i podrška za specijalizirane kompresijske kodeke koji se mogu koristiti u lancu s drugim algoritmima.

Jesu li blokovi samo neobrađeni podaci?

Nije potpuno sirovo. Postoje nizovi. Ako imate numerički stupac, tada se brojevi u retku postavljaju u polje.

To je jasno.

Alexey, primjer koji je bio s uniqExactom preko IP-ova, tj. činjenica da uniqExactu treba više vremena za izračunavanje po linijama nego po brojevima, i tako dalje. Što ako koristimo fintu ušima i zabacimo u trenutku lekture? Odnosno, čini se da ste rekli da na našem disku nije mnogo drugačije. Ako čitamo linije s diska i cast, hoće li naši agregati biti brži ili ne? Ili ćemo tu ipak malo dobiti? Čini mi se da ste ovo testirali, ali iz nekog razloga to niste naveli u mjerilu.

Mislim da će biti sporije nego bez lijevanja. U ovom slučaju, IP adresa mora biti analizirana iz niza. Naravno, u ClickHouseu je optimizirana i naša analiza IP adresa. Jako smo se trudili, ali eto ti brojeva napisanih u desettisućitnom obliku. Vrlo neugodno. S druge strane, funkcija uniqExact radit će sporije na nizovima, ne samo zato što se radi o nizovima, već i zato što je odabrana drugačija specijalizacija algoritma. Nizovi se jednostavno drugačije obrađuju.

Što ako uzmemo primitivniji tip podataka? Na primjer, zapisali smo korisnički id, koji imamo, zapisali ga kao redak, a zatim ga šifrirali, hoće li biti zabavnije ili ne?

Sumnjam. Mislim da će biti još tužnije, jer ipak je raščlanjivanje brojeva ozbiljan problem. Čini mi se da je taj kolega čak dao izvješće o tome kako je teško raščlaniti brojeve u desettisućitnom obliku, ali možda i nije.

Alexey, hvala vam puno na izvješću! I hvala vam puno za ClickHouse! Imam pitanje o planovima. Postoje li planovi za značajku za nepotpuno ažuriranje rječnika?

Odnosno djelomično ponovno pokretanje?

Da da. Poput mogućnosti postavljanja MySQL polja tamo, tj. ažuriranja nakon tako da se samo ti podaci učitavaju ako je rječnik jako velik.

Vrlo zanimljiva značajka. I mislim da je neka osoba to predložila u našem chatu. Možda si to bio čak i ti.

Ne mislim tako.

Super, sad se pokazalo da postoje dva zahtjeva. I polako to možete početi činiti. Ali želim vas odmah upozoriti da je ovu značajku vrlo jednostavno implementirati. To jest, u teoriji, trebate samo napisati broj verzije u tablicu i zatim napisati: verzija manja od takve i takve. To znači da ćemo, najvjerojatnije, ovo ponuditi entuzijastima. Jeste li entuzijast?

Da, ali, nažalost, ne u C++.

Znaju li vaši kolege pisati u C++?

Naći ću nekoga.

Sjajno*.

* značajka je dodana dva mjeseca nakon izvješća - autor pitanja ju je razvio i poslao svoju zahtjev za povlačenjem.

Hvala vam!

Zdravo! Hvala na izvješću! Spomenuli ste da je ClickHouse vrlo dobar u konzumiranju svih resursa koji su mu dostupni. I govornik pored Luxoft-a govorio je o svom rješenju za Rusku poštu. Rekao je da im se ClickHouse jako svidio, ali ga nisu stavili umjesto glavnog konkurenta upravo zato što je gutao sav CPU. I nisu ga mogli uključiti u svoju arhitekturu, u svoj ZooKeeper s dokerima. Je li moguće nekako ograničiti ClickHouse da ne konzumira sve što mu postane dostupno?

Da, moguće je i vrlo jednostavno. Ako želite potrošiti manje jezgri, samo pišite set max_threads = 1. I to je to, izvršit će zahtjev u jednoj jezgri. Štoviše, možete odrediti različite postavke za različite korisnike. Dakle nema problema. I recite kolegama iz Luxoft-a da nije dobro što ovu postavku nisu našli u dokumentaciji.

Alexey, zdravo! Htio bih pitati o ovom pitanju. Ovo nije prvi put da čujem da mnogi ljudi počinju koristiti ClickHouse kao pohranu za zapise. U izvješću ste rekli da to ne radite, tj. ne morate pohranjivati ​​duge nizove. Što mislite o tome?

Prvo, dnevnici u pravilu nisu dugački nizovi. Ima, naravno, i izuzetaka. Na primjer, neki servis napisan u Javi izbaci iznimku, zapisuje se. I tako u beskonačnoj petlji, a mjesta na tvrdom disku ponestaje. Rješenje je vrlo jednostavno. Ako su linije jako dugačke, izrežite ih. Što znači dugo? Deseci kilobajta su loši*.

* u posljednjim verzijama ClickHouse-a omogućena je “adaptive index granularity” koja većim dijelom eliminira problem pohranjivanja dugih redaka.

Je li kilobajt normalan?

To je normalno.

Zdravo! Hvala na izvješću! Već sam pitao o tome u chatu, ali ne sjećam se jesam li dobio odgovor. Postoje li planovi da se nekako proširi odjeljak WITH na način CTE-a?

Ne još. Naš dio SA je pomalo neozbiljan. To je za nas kao mala značajka.

Razumijem. Hvala vam!

Hvala na izvješću! Vrlo zanimljivo! Globalno pitanje. Postoje li planovi za modificiranje brisanja podataka, možda u obliku nekakvih zaglavaka?

Obavezno. Ovo je naš prvi zadatak u redu. Sada aktivno razmišljamo o tome kako sve učiniti ispravno. I trebali biste početi pritiskati tipkovnicu*.

* pritiskao tipke na tipkovnici i radio sve.

Hoće li to nekako utjecati na performanse sustava ili ne? Hoće li umetanje biti jednako brzo kao sada?

Možda će sama brisanja i sama ažuriranja biti vrlo teška, ali to neće utjecati na izvedbu odabira ili izvedbu umetanja.

I još jedno malo pitanje. Na prezentaciji ste govorili o primarnom ključu. Sukladno tome, imamo particioniranje, koje je standardno mjesečno, točno? A kada postavimo datumski raspon koji stane u mjesec, tada se čita samo ova particija, zar ne?

Da.

Pitanje. Ako ne možemo odabrati niti jedan primarni ključ, je li onda ispravno to učiniti posebno prema polju "Datum" tako da u pozadini bude manje preslagivanja ovih podataka tako da se uklapaju na uredniji način? Ako nemate upite raspona i ne možete čak ni odabrati nijedan primarni ključ, isplati li se staviti datum u primarni ključ?

Da.

Možda ima smisla u primarni ključ staviti polje koje će bolje komprimirati podatke ako su poredani po ovom polju. Na primjer, ID korisnika. Korisnik, na primjer, ode na istu stranicu. U ovom slučaju, stavite ID korisnika i vrijeme. I tada će vaši podaci biti bolje komprimirani. Što se tiče datuma, ako stvarno nemate i nikada nemate upite o rasponu datuma, onda ne morate stavljati datum u primarni ključ.

U redu, puno hvala!

Izvor: www.habr.com

Dodajte komentar