uvod
To poročilo sem podal v angleščini na konferenci GopherCon Russia 2019 v Moskvi in v ruščini na srečanju v Nižnem Novgorodu. Govorimo o bitnem indeksu - manj pogost kot B-drevo, a nič manj zanimiv. Skupna raba
Pogledali bomo, kako deluje bitni indeks, kdaj je boljši, kdaj slabši od drugih indeksov in v katerih primerih je bistveno hitrejši od njih; Poglejmo, kateri priljubljeni DBMS že imajo bitne indekse; Poskusimo napisati svoje v Go. In "za posladek" bomo uporabili že pripravljene knjižnice za ustvarjanje lastne super hitre specializirane baze podatkov.
Resnično upam, da vam bodo moja dela koristna in zanimiva. Pojdi!
Predstavitev
Pozdravljeni vsi skupaj! Ura je šest zvečer in vsi smo zelo utrujeni. Odličen čas za pogovor o dolgočasni teoriji indeksa baze podatkov, kajne? Ne skrbite, tu in tam bom imel nekaj vrstic izvorne kode. 🙂
Šalo na stran, poročilo je polno informacij, časa pa nimamo veliko. Pa začnimo.
Danes bom govoril o naslednjem:
- kaj so indeksi;
- kaj je bitni indeks;
- kje se uporablja in kje se NE uporablja in zakaj;
- enostavna implementacija v Go in malo borbe s prevajalnikom;
- nekoliko manj preprosta, a veliko bolj produktivna implementacija v Go assembler;
- “težave” bitnih indeksov;
- obstoječe izvedbe.
Kaj so torej indeksi?
Indeks je ločena podatkovna struktura, ki jo vzdržujemo in posodabljamo poleg glavnih podatkov. Uporablja se za pospešitev iskanja. Brez indeksov bi iskanje zahtevalo popolno pregledovanje podatkov (postopek, imenovan popolno skeniranje), ta postopek pa ima linearno algoritemsko zapletenost. Toda zbirke podatkov običajno vsebujejo ogromne količine podatkov in linearna kompleksnost je prepočasna. V idealnem primeru bi dobili logaritemsko ali konstantno.
To je zelo zapletena tema, polna razlik in kompromisov, a po pregledu desetletij razvoja in raziskav baze podatkov sem pripravljen reči, da obstaja le nekaj široko uporabljenih pristopov za ustvarjanje indeksov baze podatkov.
Prvi pristop je hierarhično zmanjšanje iskalnega prostora, tako da se iskalni prostor razdeli na manjše dele.
Običajno to počnemo z uporabo različnih vrst dreves. Primer bi bila velika škatla materialov v vaši omari, ki vsebuje manjše škatle materialov, razdeljenih na različne teme. Če potrebujete materiale, jih boste verjetno iskali v škatli z napisom "Materiali" in ne v škatli z napisom "Piškotki", kajne?
Drugi pristop je takojšnja izbira želenega elementa ali skupine elementov. To naredimo v zgoščenih zemljevidih ali obratnih indeksih. Uporaba zgoščenih zemljevidov je zelo podobna prejšnjemu primeru, vendar imate namesto škatle škatel v svoji omari kup majhnih škatel končnih predmetov.
Tretji pristop je odprava potrebe po iskanju. To naredimo s filtri Bloom ali filtri kukavice. Prvi dajo odgovor takoj in vam prihranijo iskanje.
Zadnji pristop je, da v celoti izkoristimo vso moč, ki nam jo daje sodobna strojna oprema. Točno to počnemo v bitnih indeksih. Da, pri njihovi uporabi moramo včasih pregledati celoten indeks, vendar to počnemo super učinkovito.
Kot sem rekel, je tema indeksov baz podatkov obsežna in polna kompromisov. To pomeni, da včasih lahko uporabimo več pristopov hkrati: če želimo iskanje še pospešiti ali če moramo pokriti vse možne vrste iskanja.
Danes bom govoril o najmanj znanem pristopu med temi - o bitnih indeksih.
Kdo sem jaz, da govorim o tej temi?
Delam kot vodja ekipe pri Badoo (morda bolj poznate naš drugi izdelek, Bumble). Imamo že več kot 400 milijonov uporabnikov po vsem svetu in številne funkcije, ki izberejo najboljše ujemanje zanje. To naredimo s storitvami po meri, vključno z indeksi bitnih slik.
Kaj je torej indeks bitne slike?
Indeksi bitnih slik, kot že ime pove, uporabljajo bitne slike ali bitne nize za implementacijo iskalnega indeksa. S ptičje perspektive je ta indeks sestavljen iz ene ali več takšnih bitnih slik, ki predstavljajo poljubne entitete (kot so ljudje) in njihove lastnosti ali parametre (starost, barva oči itd.), ter algoritem, ki uporablja bitne operacije (IN, ALI, NE). ), da odgovorite na iskalno poizvedbo.
Povedali so nam, da so bitni indeksi najprimernejši in zelo zmogljivi za primere iskanj, ki združujejo poizvedbe v številnih stolpcih z nizko kardinalnostjo (pomislite na "barvo oči" ali "zakonski stan" v primerjavi z nečim, kot je "oddaljenost od središča mesta"). Kasneje pa bom pokazal, da dobro delujejo tudi za stolpce z visoko kardinalnostjo.
Oglejmo si najpreprostejši primer indeksa bitne slike.
Predstavljajte si, da imamo seznam moskovskih restavracij z binarnimi lastnostmi, kot so te:
- v bližini metroja;
- na voljo je zasebno parkirišče;
- obstaja veranda (ima teraso);
- lahko rezervirate mizo (sprejema rezervacije);
- primerno za vegetarijance (vegan friendly);
- drago (drago).
Vsaki restavraciji dajmo zaporedno številko, ki se začne z 0, in dodelimo pomnilnik za 6 bitnih slik (eno za vsako značilnost). Te bitne slike bomo nato zapolnili glede na to, ali ima restavracija to lastnost ali ne. Če ima restavracija 4 verando, bo bit št. 4 v bitni sliki »ima verando« nastavljen na 1 (če verande ni, potem na 0).
Zdaj imamo najpreprostejši možen indeks bitne slike in ga lahko uporabimo za odgovore na poizvedbe, kot so:
- »Pokaži mi vegetarijance prijazne restavracije«;
- "Pokaži mi poceni restavracije z verando, kjer lahko rezerviraš mizo."
kako Gremo pogledat. Prva zahteva je zelo preprosta. Vse kar moramo storiti je, da vzamemo bitno sliko »vegetarijancem prijazno« in jo spremenimo v seznam restavracij, katerih deli so izpostavljeni.
Druga zahteva je nekoliko bolj zapletena. Uporabiti moramo bitno sliko NOT na »dragi« bitni sliki, da dobimo seznam poceni restavracij, nato IN to z bitno sliko »ali lahko rezerviram mizo« in IN rezultat z bitno sliko »tam je veranda«. Nastala bitna slika bo vsebovala seznam ustanov, ki izpolnjujejo vsa naša merila. V tem primeru je to samo restavracija Yunost.
Vključenih je veliko teorije, a ne skrbite, kodo bomo videli zelo kmalu.
Kje se uporabljajo bitni indeksi?
Če googlate bitne indekse, bo 90 % odgovorov tako ali drugače povezanih z Oracle DB. Toda drugi DBMS verjetno podpirajo tudi tako kul stvar, kajne? res ne.
Pojdimo skozi seznam glavnih osumljencev.
MySQL še ne podpira bitnih indeksov, vendar obstaja predlog, ki predlaga dodajanje te možnosti (
PostgreSQL ne podpira bitnih indeksov, ampak uporablja preproste bitne slike in bitne operacije za združevanje rezultatov iskanja v več drugih indeksih.
Tarantool ima bitset indekse in podpira preprosto iskanje po njih.
Redis ima preprosta bitna polja
MongoDB še ne podpira bitnih indeksov, vendar obstaja tudi predlog, ki predlaga, da se doda ta možnost
Elasticsearch interno uporablja bitne slike
- Toda v naši hiši se je pojavila nova soseda: Pilosa. To je nova nerelacijska zbirka podatkov, napisana v Go. Vsebuje le bitne indekse in vse temelji na njih. O tem bomo govorili malo kasneje.
Implementacija v Go
Toda zakaj se indeksi bitnih slik tako redko uporabljajo? Preden odgovorim na to vprašanje, bi vam rad pokazal, kako implementirati zelo preprost indeks bitne slike v Go.
Bitne slike so v bistvu samo kosi podatkov. V Go za to uporabimo rezine bajtov.
Imamo eno bitno sliko za eno značilnost restavracije in vsak bit v bitni sliki označuje, ali ima določena restavracija to lastnost ali ne.
Potrebovali bomo dve pomožni funkciji. Ena bo uporabljena za zapolnitev bitnih slik z naključnimi podatki. Naključno, vendar z določeno verjetnostjo, da ima restavracija vsak lastnino. Na primer, verjamem, da je v Moskvi zelo malo restavracij, kjer ne morete rezervirati mize, in zdi se mi, da je približno 20% obratov primernih za vegetarijance.
Druga funkcija bo bitno sliko pretvorila v seznam restavracij.
Za odgovor na poizvedbo »Pokaži mi poceni restavracije, ki imajo teraso in lahko rezervirajo«, potrebujemo dve bitni operaciji: NE in IN.
Našo kodo lahko nekoliko poenostavimo z uporabo bolj zapletenega operatorja IN NE.
Za vsako od teh operacij imamo funkcije. Oba gresta skozi rezine, iz vsake vzameta ustrezne elemente, jih z bitno operacijo združita in rezultat vneseta v nastalo rezino.
In zdaj lahko uporabimo naše bitne slike in funkcije, da odgovorimo na iskalno poizvedbo.
Zmogljivost ni tako visoka, čeprav so funkcije zelo preproste in smo prihranili veliko denarja, ker nismo vrnili nove nastale rezine ob vsakem klicu funkcije.
Po malem profiliranju s pprofom sem opazil, da prevajalniku Go manjka ena zelo preprosta, a zelo pomembna optimizacija: vstavljanje funkcij.
Dejstvo je, da se prevajalnik Go strašno boji zank, ki gredo skozi rezine, in kategorično zavrača vstavljanje funkcij, ki vsebujejo takšne zanke.
Vendar se ne bojim in lahko prevaram prevajalnik z uporabo goto namesto zanke, kot v dobrih starih časih.
In kot lahko vidite, bo zdaj prevajalnik z veseljem vgradil našo funkcijo! Posledično nam uspe prihraniti približno 2 mikrosekundi. Ni slabo!
Drugo ozko grlo je enostavno opaziti, če pozorno pogledate izhod sestavljanja. Prevajalnik je dodal preverjanje meje rezine prav znotraj naše najbolj vroče zanke. Dejstvo je, da je Go varen jezik, prevajalnik se boji, da so moji trije argumenti (tri rezine) različnih velikosti. Navsezadnje bo obstajala teoretična možnost pojava tako imenovanega prelivanja medpomnilnika.
Pomirimo prevajalnik tako, da mu pokažemo, da so vse rezine enake velikosti. To lahko storimo tako, da na začetku naše funkcije dodamo preprosto preverjanje.
Ko to vidi, prevajalnik veselo preskoči preverjanje in na koncu prihranimo dodatnih 500 nanosekund.
Velike zaplete
V redu, uspelo nam je iztisniti nekaj zmogljivosti iz naše preproste izvedbe, vendar je ta rezultat dejansko veliko slabši, kot je mogoče s trenutno strojno opremo.
Vse, kar počnemo, so osnovne bitne operacije, naši procesorji pa jih izvajajo zelo učinkovito. Toda na žalost svoj procesor »nahranimo« z zelo majhnimi deli. Naše funkcije izvajajo operacije na osnovi bajt za bajtom. Našo kodo lahko zelo enostavno prilagodimo za delo z 8-bajtnimi kosi z uporabo rezin UInt64.
Kot lahko vidite, ta majhna sprememba pospeši naš program za osemkrat s povečanjem velikosti serije za osemkrat. Dobiček lahko rečemo, da je linearen.
Implementacija v asemblerju
A to še ni konec. Naši procesorji lahko delajo s kosi velikosti 16, 32 in celo 64 bajtov. Takšne "široke" operacije imenujemo enojni ukaz več podatkov (SIMD; eno navodilo, veliko podatkov), proces preoblikovanja kode, tako da uporablja takšne operacije, pa se imenuje vektorizacija.
Na žalost prevajalnik Go še zdaleč ni odličen pri vektorizaciji. Trenutno je edini način za vektorizacijo kode Go ta, da te operacije vzamete in izvedete ročno z uporabo Go asemblerja.
Go montažer je čudna zver. Verjetno veste, da je zbirni jezik nekaj, kar je močno povezano z arhitekturo računalnika, za katerega pišete, vendar v Go ni tako. Go assembler je bolj podoben IRL (intermediate representation language) ali vmesnemu jeziku: je praktično neodvisen od platforme. Rob Pike je odlično nastopil
Poleg tega Go uporablja nenavaden format Plan 9, ki se razlikuje od splošno sprejetih formatov AT&T in Intel.
Lahko rečemo, da ročno pisanje Go assemblerja ni najbolj zabavno.
Toda na srečo že obstajata dve orodji na visoki ravni, ki nam pomagata napisati Go assembler: PeachPy in avo. Oba pripomočka ustvarita zbirnik Go iz kode višje ravni, napisane v Pythonu oziroma Go.
Ti pripomočki poenostavijo stvari, kot so dodeljevanje registrov, pisanje zank in na splošno poenostavijo postopek vstopa v svet programiranja sestavljanja v Go.
Uporabljali bomo avo, tako da bodo naši programi skoraj običajni Go programi.
Tako je videti najenostavnejši primer programa avo. Imamo funkcijo main(), ki v sebi definira funkcijo Add(), katere pomen je seštevanje dveh števil. Tukaj so pomožne funkcije za pridobivanje parametrov po imenu in enega od brezplačnih in ustreznih registrov procesorja. Vsaka operacija procesorja ima ustrezno funkcijo na avo, kot je razvidno iz ADDQ. Na koncu vidimo pomožno funkcijo za shranjevanje nastale vrednosti.
S klicem go generate bomo izvedli program na avo in posledično bosta generirani dve datoteki:
- add.s z nastalo kodo v Go assemblerju;
- stub.go s funkcijskimi glavami za povezovanje dveh svetov: Go in asembler.
Zdaj, ko smo videli, kaj avo počne in kako, si poglejmo naše funkcije. Implementiral sem tako skalarno kot vektorsko (SIMD) različico funkcij.
Najprej si poglejmo skalarne različice.
Kot v prejšnjem primeru zahtevamo brezplačen in veljaven register splošnega namena, ni nam treba izračunati odmikov in velikosti za argumente. avo naredi vse to namesto nas.
Včasih smo uporabljali oznake in goto (ali skoke) za izboljšanje zmogljivosti in pretentanje prevajalnika Go, zdaj pa to počnemo od začetka. Gre za to, da so cikli koncept višje ravni. V asemblerju imamo samo oznake in skoke.
Preostala koda bi morala biti že znana in razumljiva. Posnemamo zanko z oznakami in skoki, vzamemo majhen košček podatkov iz naših dveh rezin, ju združimo z bitno operacijo (IN NE v tem primeru) in nato vstavimo rezultat v nastalo rezino. Vse.
Tako izgleda končna koda za sestavljanje. Ni nam bilo treba izračunati odmikov in velikosti (označeno z zeleno) ali slediti uporabljenim registrom (poudarjeno z rdečo).
Če primerjamo zmogljivost izvedbe zbirnega jezika z zmogljivostjo najboljše izvedbe v Go, bomo videli, da je enaka. In to je pričakovano. Navsezadnje nismo naredili nič posebnega – le posnemali smo, kar bi naredil Go prevajalnik.
Na žalost ne moremo prisiliti prevajalnika, da vgradi naše funkcije, napisane v zbirnem jeziku. Prevajalnik Go trenutno nima takšne funkcije, čeprav že nekaj časa obstaja zahteva za dodajanje.
Zato je nemogoče izkoristiti majhne funkcije v zbirnem jeziku. Napisati moramo velike funkcije ali uporabiti nov paket math/bits ali zaobiti jezik asembler.
Poglejmo zdaj vektorske različice naših funkcij.
Za ta primer sem se odločil uporabiti AVX2, zato bomo uporabili operacije, ki delujejo na 32-bajtnih delih. Struktura kode je zelo podobna skalarni različici: nalaganje parametrov, zahtevanje brezplačnega skupnega registra itd.
Ena od novosti je, da širše vektorske operacije uporabljajo posebne široke registre. V primeru 32-bajtnih kosov so to registri s predpono Y. Zato v kodi vidite funkcijo YMM(). Če bi uporabljal AVX-512 s 64-bitnimi kosi, bi bila predpona Z.
Druga novost je, da sem se odločil uporabiti optimizacijo, imenovano odvijanje zanke, kar pomeni ročno izvedbo osmih operacij zanke, preden skočim na začetek zanke. Ta optimizacija zmanjša število vej v kodi in je omejena s številom razpoložljivih brezplačnih registrov.
No, kaj pa uspešnost? Ona je lepa! Dosegli smo približno sedemkratno pospešitev v primerjavi z najboljšo rešitvijo Go. Impresivno, kajne?
Toda celo to izvedbo bi lahko potencialno pospešili z uporabo AVX-512, vnaprejšnjega pridobivanja ali JIT (just-in-time compiler) za razporejevalnik poizvedb. Ampak to je vsekakor tema za ločeno poročilo.
Težave z indeksi bitnih slik
Zdaj, ko smo si že ogledali preprosto implementacijo indeksa bitne slike v Go in veliko bolj produktivno implementacijo v zbirnem jeziku, se končno pogovorimo o tem, zakaj se indeksi bitne slike tako redko uporabljajo.
Starejši članki omenjajo tri težave z bitnimi indeksi, novejši članki pa trdim, da niso več pomembni. Ne bomo se poglabljali v vsakega od teh problemov, ampak jih bomo pogledali površno.
Problem visoke kardinalnosti
Povedali so nam torej, da so bitni indeksi primerni samo za polja z nizko kardinalnostjo, to je tista, ki imajo malo vrednosti (na primer spol ali barva oči), razlog pa je v tem, da običajna predstavitev takih polj (ena bit na vrednost) bo v primeru visoke kardinalnosti zavzelo preveč prostora, poleg tega pa bodo ti indeksi bitne slike slabo (redko) zapolnjeni.
Včasih lahko uporabimo drugačno predstavitev, na primer standardno, ki jo uporabljamo za predstavitev števil. Toda pojav algoritmov za stiskanje je vse spremenil. V zadnjih desetletjih so znanstveniki in raziskovalci iznašli veliko število algoritmov za stiskanje bitnih slik. Njihova glavna prednost je, da za izvajanje bitnih operacij ni treba razpakirati bitnih slik – bitne operacije lahko izvajamo neposredno na stisnjenih bitnih slikah.
V zadnjem času so se začeli pojavljati hibridni pristopi, kot so rooring bitmaps. Hkrati uporabljajo tri različne predstavitve za bitne slike - same bitne slike, nize in tako imenovane bitne nize - in uravnotežijo med njimi, da povečajo zmogljivost in zmanjšajo porabo pomnilnika.
V najbolj priljubljenih aplikacijah najdete bučne bitne slike. Obstaja že ogromno izvedb za najrazličnejše programske jezike, vključno z več kot tremi izvedbami za Go.
Drug pristop, ki nam lahko pomaga pri soočanju z visoko kardinalnostjo, se imenuje združevanje. Predstavljajte si, da imate polje, ki predstavlja višino osebe. Višina je število s plavajočo vejico, vendar si ljudje tega ne predstavljamo tako. Pri nas ni razlike med višino 185,2 cm in 185,3 cm.
Izkazalo se je, da lahko podobne vrednosti združimo v skupine znotraj 1 cm.
In če vemo tudi, da je zelo malo ljudi nižjih od 50 cm in višjih od 250 cm, potem lahko polje z neskončno kardinalnostjo v bistvu spremenimo v polje s kardinalnostjo približno 200 vrednosti.
Seveda lahko po potrebi dodatno filtriramo naknadno.
Težava z visoko pasovno širino
Naslednja težava z indeksi bitnih slik je, da je njihovo posodabljanje lahko zelo drago.
Podatkovne zbirke morajo imeti možnost posodabljanja podatkov, medtem ko potencialno na stotine drugih poizvedb išče podatke. Ključavnice potrebujemo, da se izognemo težavam s sočasnim dostopom do podatkov ali drugim težavam pri skupni rabi. In kjer je ena velika ključavnica, se pojavi problem - spor za ključavnico, ko ta ključavnica postane ozko grlo.
To težavo je mogoče rešiti ali se ji izogniti z uporabo razrezov ali indeksov z različicami.
Sharding je preprosta in znana stvar. Indeks bitne slike lahko razdrobite tako kot vse druge podatke. Namesto ene velike ključavnice boste dobili kup majhnih ključavnic in se tako znebili spora glede ključavnic.
Drugi način za rešitev težave je uporaba verzioniranih indeksov. Lahko imate eno kopijo indeksa, ki jo uporabljate za iskanje ali branje, in eno, ki jo uporabljate za pisanje ali posodabljanje. In enkrat v določenem časovnem obdobju (na primer enkrat na 100 ms ali 500 ms) jih podvojiš in zamenjaš. Seveda je ta pristop uporaben samo v primerih, ko vaša aplikacija lahko obravnava rahlo zaostajajoč iskalni indeks.
Ta dva pristopa je mogoče uporabiti hkrati: lahko imate razdrobljen indeks z različicami.
Bolj zapletene poizvedbe
Zadnja težava z indeksi bitnih slik je, da nam povedo, da niso najbolj primerni za bolj zapletene vrste poizvedb, kot so poizvedbe razpona.
Dejansko, če dobro pomislite, bitne operacije, kot so IN, ALI itd., niso preveč primerne za poizvedbe tipa "Pokaži mi hotele s cenami sob od 200 do 300 dolarjev na noč."
Naivna in zelo nespametna rešitev bi bila vzeti rezultate za vsako vrednost v dolarjih in jih združiti z bitno operacijo ALI.
Nekoliko boljša rešitev bi bila uporaba združevanja. Na primer v skupinah po 50 dolarjev. To bi naš proces pospešilo za 50-krat.
Težavo pa je enostavno rešiti tudi z uporabo pogleda, ustvarjenega posebej za tovrstne zahteve. V znanstvenih člankih se imenuje bitne slike, kodirane po območju.
V tej predstavitvi ne nastavimo le enega bita za neko vrednost (na primer 200), ampak nastavimo to vrednost in vse višje. 200 in več. Enako za 300: 300 in več. In tako naprej.
Z uporabo te predstavitve lahko odgovorimo na tovrstno iskalno poizvedbo tako, da samo dvakrat preletimo indeks. Najprej bomo dobili seznam hotelov, kjer soba stane manj ali 300 dolarjev, nato pa bomo z njega odstranili tiste, kjer je cena sobe nižja ali 199 dolarjev. pripravljena
Presenečeni boste, vendar so celo geopoizvedbe možne z uporabo bitnih indeksov. Trik je v uporabi geometrijske predstavitve, ki obdaja vašo koordinato z geometrijskim likom. Na primer S2 iz Googla. Slik mora biti mogoče prikazati v obliki treh ali več sekajočih se črt, ki jih je mogoče oštevilčiti. Na ta način lahko našo geopoizvedbo spremenimo v več poizvedb "vzdolž vrzeli" (vzdolž teh oštevilčenih vrstic).
Pripravljene rešitve
Upam, da sem vas malo zanimal in imate zdaj v svojem arzenalu še eno uporabno orodje. Če boste kdaj morali narediti kaj takega, boste vedeli, kam iskati.
Vendar nimajo vsi časa, potrpljenja ali sredstev za ustvarjanje bitnih indeksov iz nič. Predvsem naprednejši, ki uporabljajo na primer SIMD.
Na srečo obstaja več že pripravljenih rešitev, ki vam lahko pomagajo.
Rjoveče bitne slike
Prvič, obstaja ista knjižnica bitnih slik, o kateri sem že govoril. Vsebuje vse potrebne vsebnike in bitne operacije, ki jih boste potrebovali za izdelavo polnopravnega indeksa bitne slike.
Na žalost trenutno nobena od implementacij Go ne uporablja SIMD, kar pomeni, da so implementacije Go na primer manj zmogljive od implementacij C.
Pilosa
Drug izdelek, ki vam lahko pomaga, je Pilosa DBMS, ki ima dejansko samo bitne indekse. To je razmeroma nova rešitev, vendar z veliko hitrostjo osvaja srca.
Pilosa interno uporablja bučne bitne slike in vam daje možnost, da jih uporabljate, poenostavlja in razlaga vse stvari, o katerih sem govoril zgoraj: združevanje, bitne slike, kodirane z obsegom, koncept polja itd.
Oglejmo si na hitro primer uporabe Pilosa za odgovor na vprašanje, ki ga že poznate.
Primer je zelo podoben tistemu, kar ste videli prej. Ustvarimo odjemalca za strežnik Pilosa, ustvarimo indeks in potrebna polja, nato naša polja izpolnimo z naključnimi podatki z verjetnostmi in na koncu izvedemo že znano poizvedbo.
Nato uporabimo NOT na polju "expensive", nato presekamo rezultat (ali IN) s poljem "terasa" in poljem "rezervacije". In končno dobimo končni rezultat.
Resnično upam, da se bo ta nova vrsta indeksa v doglednem času pojavila tudi v DBMS-jih, kot sta MySQL in PostgreSQL - bitmap indeksi.
Zaključek
Če še niste zaspali, hvala. Zaradi omejenega časa sem se moral na kratko dotakniti mnogih tem, a upam, da je bil pogovor koristen in morda celo motivirajoč.
Bitne indekse je dobro poznati, tudi če jih trenutno ne potrebujete. Naj bodo še eno orodje v vaši orodjarni.
Ogledali smo si različne trike za zmogljivost za Go in stvari, ki jih prevajalnik Go še ne obvlada najbolje. Toda to je popolnoma koristno vedeti za vsakega programerja Go.
To je vse, kar sem ti hotel povedati. Hvala vam!
Vir: www.habr.com