{"id":74737,"date":"2020-03-20T08:43:14","date_gmt":"2020-03-20T05:43:14","guid":{"rendered":"https:\/\/prohoster.info\/blog\/administrirovanie\/optimizacziya-strok-v-clickhouse-doklad-yandeksa"},"modified":"2020-03-20T08:43:14","modified_gmt":"2020-03-20T05:43:14","slug":"optimizacziya-strok-v-clickhouse-doklad-yandeksa","status":"publish","type":"post","link":"https:\/\/prohoster.info\/sv\/blog\/administrirovanie\/optimizacziya-strok-v-clickhouse-doklad-yandeksa","title":{"rendered":"Optimering av str\u00e4ngar i ClickHouse. Presentation fr\u00e5n Yandex","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p>Den analytiska databasen ClickHouse hanterar en m\u00e4ngd olika str\u00e4ngar och f\u00f6rbrukar resurser. F\u00f6r att p\u00e5skynda systemets arbete l\u00e4ggs st\u00e4ndigt till nya optimeringar. Utvecklaren av ClickHouse, Nikolai Kochetov, ber\u00e4ttar om str\u00e4ngdatatypen, inklusive den nya typen LowCardinality, och f\u00f6rklarar hur man kan snabba upp arbetet med str\u00e4ngar. <\/p>\n<p><center><div class=\"youtube-placeholder\" data-id=\"rqf-ILRgBdY\" onclick=\"loadVideo(this)\">\r\n        <img decoding=\"async\" src=\"https:\/\/img.youtube.com\/vi\/rqf-ILRgBdY\/hqdefault.jpg\" alt=\"Spela video\" loading=\"lazy\" width=\"480\" height=\"360\" style=\"width:100%;height:auto;\">\r\n        <div class=\"play-button\"><\/div>\r\n    <\/div><\/center><br \/>\n\u2014 L\u00e5t oss f\u00f6rst g\u00e5 igenom hur vi kan lagra str\u00e4ngar. <br \/>\n<noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><br \/>\n<img decoding=\"async\" alt=\"Optimering av str\u00e4ngar i ClickHouse. Presentation fr\u00e5n Yandex\" src=\"\/wp-content\/uploads\/2020\/03\/5e38e903aaaf54a533bd3026e76a14be.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nVi har str\u00e4ngdatatyper. String \u00e4r bra som standard och b\u00f6r n\u00e4stan alltid anv\u00e4ndas. Den har en liten overhead \u2014 9 byte per str\u00e4ng. Om vi vill att storleken p\u00e5 str\u00e4ngarna ska vara fast och k\u00e4nd p\u00e5 f\u00f6rhand, \u00e4r det b\u00e4ttre att anv\u00e4nda FixedString. H\u00e4r kan vi ange det antal byte vi beh\u00f6ver, vilket \u00e4r praktiskt f\u00f6r data som IP-adresser eller hash-funktioner. <\/p>\n<p><img decoding=\"async\" alt=\"Optimering av str\u00e4ngar i ClickHouse. Presentation fr\u00e5n Yandex\" src=\"\/wp-content\/uploads\/2020\/03\/eaae898fb5163cb1c070c34a13f6f160.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nSj\u00e4lvklart, ibland g\u00e5r n\u00e5got l\u00e5ngsamt. Anta att du g\u00f6r en f\u00f6rfr\u00e5gan till en tabell. ClickHouse l\u00e4ser en ganska stor m\u00e4ngd data, l\u00e5t s\u00e4ga i hastighet av 100 GB\/s, medan str\u00e4ngar hanteras v\u00e4ldigt lite. Vi har tv\u00e5 tabeller som lagrar n\u00e4stan identiska data. Fr\u00e5n den andra tabellen l\u00e4ser ClickHouse data snabbare, men antalet str\u00e4ngar som l\u00e4ses per sekund \u00e4r tre g\u00e5nger l\u00e4gre. <\/p>\n<p><img decoding=\"async\" alt=\"Optimering av str\u00e4ngar i ClickHouse. Presentation fr\u00e5n Yandex\" src=\"\/wp-content\/uploads\/2020\/03\/be7cc47e628112bb212ed0e8ff9091ed.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nOm vi tittar p\u00e5 storleken p\u00e5 de komprimerade data, kommer den att visa sig vara n\u00e4stan likv\u00e4rdig. I sj\u00e4lva verket \u00e4r de samma data skrivna i tabellerna \u2014 den f\u00f6rsta miljarden siffror \u2014 men i den f\u00f6rsta kolumnen skrivs de som UInt64, och i den andra som String. P\u00e5 grund av detta tar den andra f\u00f6rfr\u00e5gan l\u00e4ngre tid att l\u00e4sa data fr\u00e5n disken och att dekomprimera dem. <\/p>\n<p><img decoding=\"async\" alt=\"Optimering av str\u00e4ngar i ClickHouse. Presentation fr\u00e5n Yandex\" src=\"\/wp-content\/uploads\/2020\/03\/c699103cecd972fcee73841cc35716d6.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nH\u00e4r \u00e4r ett annat exempel. Anta att det finns ett f\u00f6rutbest\u00e4mt antal str\u00e4ngar, begr\u00e4nsat till en konstant 1000 eller 10 000, och som praktiskt taget aldrig f\u00f6r\u00e4ndras. F\u00f6r detta fall passar datatypen Enum, i ClickHouse finns det tv\u00e5 \u2014 Enum8 och Enum16. Genom att lagra i Enum kan vi snabbt bearbeta f\u00f6rfr\u00e5gningarna. <\/p>\n<p>I ClickHouse finns det optimeringar f\u00f6r GROUP BY, IN, DISTINCT och optimeringar f\u00f6r vissa funktioner, till exempel f\u00f6r att j\u00e4mf\u00f6ra med en konstant str\u00e4ng. Sj\u00e4lvklart omvandlas inte siffror i str\u00e4ngen, utan ist\u00e4llet omvandlas den konstanta str\u00e4ngen till ett v\u00e4rde av Enum. Efter detta j\u00e4mf\u00f6rs allt snabbt. <\/p>\n<p>Men det finns ocks\u00e5 nackdelar. \u00c4ven om vi k\u00e4nner till det exakta antalet str\u00e4ngar, kan det ibland beh\u00f6va ut\u00f6kas. Om en ny str\u00e4ng kommer in \u2014 m\u00e5ste vi g\u00f6ra ett ALTER. <\/p>\n<p><img decoding=\"async\" alt=\"Optimering av str\u00e4ngar i ClickHouse. Presentation fr\u00e5n Yandex\" src=\"\/wp-content\/uploads\/2020\/03\/064c35faaf3d9de2f12d29f83197e983.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nALTER f\u00f6r Enum i ClickHouse har implementerats p\u00e5 ett optimalt s\u00e4tt. Vi skriver inte om data p\u00e5 disken, men ALTER kan vara tr\u00f6gt p\u00e5 grund av att Enum-strukturer lagras i sj\u00e4lva tabellens schema. D\u00e4rf\u00f6r m\u00e5ste vi v\u00e4nta p\u00e5 l\u00e4sf\u00f6rfr\u00e5gningar fr\u00e5n tabellen, till exempel. <\/p>\n<p>Fr\u00e5gan uppst\u00e5r, kan vi g\u00f6ra det b\u00e4ttre? Kanske, ja. Vi kan lagra Enum-strukturen inte i tabellens schema utan i ZooKeeper. Men det kan uppst\u00e5 problem relaterade till synkronisering. Till exempel, en replik f\u00e5r data, en annan g\u00f6r det inte, och om den har en gammal Enum, kan n\u00e5got g\u00e5 fel. (I ClickHouse har vi n\u00e4stan f\u00e4rdigst\u00e4llt icke-blockerande ALTER-f\u00f6rfr\u00e5gningar. N\u00e4r vi har slutf\u00f6rt dem helt beh\u00f6ver vi inte v\u00e4nta p\u00e5 l\u00e4sf\u00f6rfr\u00e5gningar.)<\/p>\n<p><img decoding=\"async\" alt=\"Optimering av str\u00e4ngar i ClickHouse. Presentation fr\u00e5n Yandex\" src=\"\/wp-content\/uploads\/2020\/03\/f5d2fdf14778f6afdd4acc8c204e163c.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nF\u00f6r att slippa kr\u00e5ngel med ALTER Enum kan vi anv\u00e4nda externa ordlistor i ClickHouse. Jag p\u00e5minner om att det \u00e4r en key-value datastruktur inuti ClickHouse, som g\u00f6r att vi kan h\u00e4mta data fr\u00e5n externa k\u00e4llor, till exempel fr\u00e5n MySQL-tabeller. <\/p>\n<p>I ClickHouse-ordlistan lagrar vi m\u00e5nga olika str\u00e4ngar, medan tabellen inneh\u00e5ller deras identifierare i form av siffror. Om vi beh\u00f6ver en str\u00e4ng, anropar vi funktionen dictGet och arbetar med den. Efter det beh\u00f6ver vi inte g\u00f6ra ALTER. F\u00f6r att l\u00e4gga till n\u00e5got i Enum, s\u00e4tter vi in det i samma MySQL-tabell. <\/p>\n<p>Men h\u00e4r uppst\u00e5r andra problem. F\u00f6r det f\u00f6rsta, ett besv\u00e4rligt syntax. Om vi vill h\u00e4mta en str\u00e4ng m\u00e5ste vi anropa dictGet. F\u00f6r det andra, brist p\u00e5 vissa optimeringar. Att j\u00e4mf\u00f6ra med en konstant str\u00e4ng f\u00f6r ordlistor g\u00e5r inte lika snabbt. <\/p>\n<p>Det kan ocks\u00e5 bli problem med uppdateringar. Anta att vi beg\u00e4rde en str\u00e4ng i cache-ordlistan, men den kom inte in i cachen. D\u00e5 m\u00e5ste vi v\u00e4nta p\u00e5 att data laddas fr\u00e5n den externa k\u00e4llan. <\/p>\n<p><img decoding=\"async\" alt=\"Optimering av str\u00e4ngar i ClickHouse. Presentation fr\u00e5n Yandex\" src=\"\/wp-content\/uploads\/2020\/03\/534818ee523a243623a5cb2babe08040.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nEn allm\u00e4n nackdel med b\u00e5da metoderna \u00e4r att vi lagrar alla nycklar p\u00e5 ett st\u00e4lle och synkroniserar dem. S\u00e5 varf\u00f6r inte lagra ordlistor lokalt? Ingen synkronisering \u2014 inga problem. Vi kan lagra ordlistan lokalt p\u00e5 en del av disken. Det vill s\u00e4ga vi utf\u00f6rde en Insert, registrerade ordlistan. Om vi arbetar med data i minnet kan vi skriva ordlistan antingen i en datablok, en kolonnkli eller i n\u00e5gon sorts cache f\u00f6r att snabba upp ber\u00e4kningarna.<\/p>\n<h3>Ordlistkodning av str\u00e4ngar <\/h3>\n<p>\nS\u00e5 kom vi till skapandet av en ny datatyp i ClickHouse \u2014 LowCardinality. Det \u00e4r ett format f\u00f6r datalagring: hur de skrivs till disken och hur de l\u00e4ses, hur de representeras i minnet och schemat f\u00f6r deras bearbetning. <\/p>\n<p><img decoding=\"async\" alt=\"Optimering av str\u00e4ngar i ClickHouse. Presentation fr\u00e5n Yandex\" src=\"\/wp-content\/uploads\/2020\/03\/e25b2eb12ff158b89b7d2dbdfb8e2e5a.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nP\u00e5 sliden finns det tv\u00e5 kolumner. Till h\u00f6ger lagras rader standardm\u00e4ssigt som typ String. Det \u00e4r uppenbart att detta \u00e4r modeller av mobiltelefoner. Till v\u00e4nster finns en likadan kolumn, men av typen LowCardinality. Den best\u00e5r av en ordbok med m\u00e5nga olika str\u00e4ngar (str\u00e4ngarna fr\u00e5n kolumnen till h\u00f6ger) och en lista med positioner (radnummer). <\/p>\n<p>Med hj\u00e4lp av dessa tv\u00e5 strukturer kan man \u00e5terskapa den ursprungliga kolumnen. Det finns ocks\u00e5 en invers index \u2014 en hash-tabell som hj\u00e4lper till att hitta positionen i ordboken baserat p\u00e5 str\u00e4ngen. Detta beh\u00f6vs f\u00f6r att snabba upp vissa f\u00f6rfr\u00e5gningar. Till exempel, om vi vill j\u00e4mf\u00f6ra, s\u00f6ka efter en str\u00e4ng i v\u00e5r kolumn eller sl\u00e5 samman dem. <\/p>\n<p>LowCardinality \u00e4r en parametertyp. Den kan vara antingen ett tal, eller n\u00e5got som lagras som ett tal, eller en str\u00e4ng, eller Nullable av dem. <\/p>\n<p><img decoding=\"async\" alt=\"Optimering av str\u00e4ngar i ClickHouse. Presentation fr\u00e5n Yandex\" src=\"\/wp-content\/uploads\/2020\/03\/d52ef0c99617238442d4f71e43af48af.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nS\u00e4rskilt med LowCardinality \u00e4r att den kan sparas f\u00f6r vissa funktioner. P\u00e5 sliden ses ett exempel p\u00e5 en f\u00f6rfr\u00e5gan. I den f\u00f6rsta raden skapade jag en kolumn av typen LowCardinality fr\u00e5n String, som jag kallade S. D\u00e4refter fr\u00e5gade jag dess namn \u2014 ClickHouse sa att det \u00e4r LowCardinality av String. Helt korrekt.<\/p>\n<p>Den tredje raden \u00e4r n\u00e4stan likadan, f\u00f6r vi anropade funktionen length. I ClickHouse returnerar funktionen length datatypen UInt64. Men v\u00e5r kolumn blev LowCardinality av UInt64. Vad \u00e4r meningen med det?<\/p>\n<p><img decoding=\"async\" alt=\"Optimering av str\u00e4ngar i ClickHouse. Presentation fr\u00e5n Yandex\" src=\"\/wp-content\/uploads\/2020\/03\/a4a51a0f1ecd68f7fffd521ab786c8a5.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nI ordboken l\u00e5g namnen p\u00e5 mobiltelefonerna, och vi till\u00e4mpade funktionen length. Nu har vi en motsvarande ordbok best\u00e5ende enbart av siffror \u2014 detta \u00e4r l\u00e4ngderna p\u00e5 str\u00e4ngarna. Kolumnen med positioner har inte \u00e4ndrats. Resultatet \u00e4r att vi har bearbetat mindre data, vilket sparade tid f\u00f6r f\u00f6rfr\u00e5gan. <\/p>\n<p>Det kan finnas andra optimeringar, till exempel att l\u00e4gga till en enkel cache. Vid ber\u00e4kning av v\u00e4rdet f\u00f6r funktionen kan man komma ih\u00e5g det och skapa ett likadant utan att ber\u00e4kna det p\u00e5 nytt. <\/p>\n<p>Det kan ocks\u00e5 g\u00f6ras en optimering av GROUP BY, eftersom v\u00e5r kolumn med ordboken redan delvis \u00e4r aggregerad \u2014 man kan snabbare ber\u00e4kna v\u00e4rden f\u00f6r hash-funktioner och ungef\u00e4rligt hitta den hink d\u00e4r man ska placera den n\u00e4sta raden. Dessutom kan man specialisera vissa aggregeringsfunktioner, till exempel uniq, eftersom man bara kan skicka ordboken dit och l\u00e4mna positionerna of\u00f6r\u00e4ndrade \u2014 s\u00e5 kommer allt att fungera snabbare. De f\u00f6rsta tv\u00e5 optimeringarna har vi redan lagt till i ClickHouse.<\/p>\n<p><img decoding=\"async\" alt=\"Optimering av str\u00e4ngar i ClickHouse. Presentation fr\u00e5n Yandex\" src=\"\/wp-content\/uploads\/2020\/03\/943e0a8ae5a37cd47164246db3a67893.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nVad h\u00e4nder om vi skapar en kolumn med v\u00e5r datatyp och s\u00e4tter in m\u00e5nga d\u00e5liga olika rader? Kommer v\u00e5rt minne att \u00f6verfullas? Nej, f\u00f6r detta finns det tv\u00e5 specialinst\u00e4llningar i ClickHouse. Den f\u00f6rsta \u00e4r low_cardinality_max_dictionary_size. Detta \u00e4r den maximala storleken p\u00e5 en ordbok som kan skrivas till disken. Ins\u00e4ttningen sker p\u00e5 f\u00f6ljande s\u00e4tt: n\u00e4r vi s\u00e4tter in data f\u00e5r vi en str\u00f6m av rader, av dem bildar vi en stor gemensam ordbok. Om ordboken blir st\u00f6rre \u00e4n v\u00e4rdet p\u00e5 inst\u00e4llningen skriver vi den aktuella ordboken till disken och de \u00e5terst\u00e5ende raderna hamnar n\u00e5gonstans \"vid sidan om\", n\u00e4ra indexen. I slut\u00e4ndan kommer vi aldrig att omber\u00e4kna den stora ordboken och f\u00e5 problem med minnet. <\/p>\n<p>Den andra inst\u00e4llningen kallas low_cardinality_use_single_dictionary_for_part. F\u00f6rest\u00e4ll dig att i det f\u00f6rra schemat, n\u00e4r vi satte in data, \u00f6verfullades v\u00e5r ordbok och vi skrev den till disken. Fr\u00e5gan uppst\u00e5r, varf\u00f6r skulle vi inte nu bilda en till exakt samma ordbok? <\/p>\n<p>N\u00e4r den \u00f6verfullnas, skriver vi den \u00e5ter till disken och b\u00f6rjar bilda den tredje. Denna inst\u00e4llning inaktiverar just den m\u00f6jligheten som standard. <\/p>\n<p>Faktum \u00e4r att flera ordb\u00f6cker kan vara anv\u00e4ndbara om vi vill s\u00e4tta in en m\u00e4ngd rader, men av misstag har satt in \"skr\u00e4p\". L\u00e5t oss s\u00e4ga att vi f\u00f6rst satte in d\u00e5liga rader, och sedan satte in bra. D\u00e5 kommer ordboken att delas upp i m\u00e5nga sm\u00e5 ordb\u00f6cker. Vissa av dem kommer att ha \"skr\u00e4p\", men de senaste kommer att vara med bra rader. Och om vi l\u00e4ser, s\u00e4g, bara den senaste granuleringen, s\u00e5 kommer allt fortfarande att fungera snabbt. <\/p>\n<p><img decoding=\"async\" alt=\"Optimering av str\u00e4ngar i ClickHouse. Presentation fr\u00e5n Yandex\" src=\"\/wp-content\/uploads\/2020\/03\/834ba3295ace98870334aa10a78e4781.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nInnan vi pratar om f\u00f6rdelarna med LowCardinality, vill jag snabbt n\u00e4mna att vi troligen inte kommer att uppn\u00e5 en minskning av data p\u00e5 disken (\u00e4ven om det kan h\u00e4nda) eftersom ClickHouse komprimerar data. Det finns en standardversion - LZ4. Det g\u00e5r ocks\u00e5 att g\u00f6ra komprimering med ZSTD. Men b\u00e5da algoritmerna implementerar redan ordboks komprimering, s\u00e5 v\u00e5r externa ordbok ClickHouse kommer inte vara s\u00e5 mycket till hj\u00e4lp. <\/p>\n<p>F\u00f6r att inte bara prata tomt har jag tagit n\u00e5gra data fr\u00e5n m\u00e4tningen \u2013 String, LowCardinality(String) och Enum \u2013 och sparat dem i olika datatyper. Det blev tre kolumner med en miljard rader. I den f\u00f6rsta kolumnen, CodePage, finns det totalt 62 v\u00e4rden. Och det syns att vi har komprimerat dem b\u00e4ttre i LowCardinality(String). String \u00e4r n\u00e5got s\u00e4mre, men det beror troligen p\u00e5 att str\u00e4ngarna \u00e4r korta; vi lagrar deras l\u00e4ngd, och de tar mycket plats och komprimeras d\u00e5ligt. <\/p>\n<p>Om vi tar PhoneModel, finns det 48 000 \u2013 redan fler, och skillnaderna mellan String och LowCardinality(String) \u00e4r n\u00e4stan obefintliga. F\u00f6r URL har vi ocks\u00e5 sparat bara 2 GB \u2013 jag tror inte att man ska lita f\u00f6r mycket p\u00e5 det. <\/p>\n<h3>Bed\u00f6mning av hastigheten<\/h3>\n<p>\n<img decoding=\"async\" alt=\"Optimering av str\u00e4ngar i ClickHouse. Presentation fr\u00e5n Yandex\" src=\"\/wp-content\/uploads\/2020\/03\/0b646570639f8f2e29b599473b84e25c.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<b><noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/toddwschneider\/nyc-taxi-data\">L\u00e4nk fr\u00e5n bilden<\/a><\/noindex><\/b><\/p>\n<p>Nu ska vi bed\u00f6ma hastigheten. F\u00f6r att g\u00f6ra det anv\u00e4nde jag ett dataset som beskriver taxiresor i New York. Det <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/toddwschneider\/nyc-taxi-data\">\u00e4r tillg\u00e4nglig<\/a><\/noindex> finns p\u00e5 GitHub. Det handlar om lite mer \u00e4n en miljard resor. Det visar plats, tid f\u00f6r start och slut, betalningsmetod, antal passagerare och till och med typ av taxi \u2013 gr\u00f6n, gul och Uber. <\/p>\n<p><img decoding=\"async\" alt=\"Optimering av str\u00e4ngar i ClickHouse. Presentation fr\u00e5n Yandex\" src=\"\/wp-content\/uploads\/2020\/03\/0901669dec01b0f956d6976e3aa8b741.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nDen f\u00f6rsta fr\u00e5gan jag st\u00e4llde var ganska enkel \u2013 jag fr\u00e5gade var man oftast best\u00e4ller taxi. F\u00f6r det beh\u00f6vs att vi tar platsen d\u00e4r taxin best\u00e4lldes, g\u00f6r en GROUP BY p\u00e5 den och r\u00e4knar antalet med funktionen count. H\u00e4r \u00e4r vad ClickHouse ger. <\/p>\n<p><img decoding=\"async\" alt=\"Optimering av str\u00e4ngar i ClickHouse. Presentation fr\u00e5n Yandex\" src=\"\/wp-content\/uploads\/2020\/03\/50983341e20bcbc1b5adbaed35f8624d.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nF\u00f6r att m\u00e4ta hastigheten p\u00e5 fr\u00e5ga skapade jag tre tabeller med samma data, men anv\u00e4nde tre olika datatyper f\u00f6r v\u00e5r startplats \u2013 String, LowCardinality och Enum. LowCardinality och Enum visade sig vara fem g\u00e5nger snabbare \u00e4n String. Enum \u00e4r snabbare eftersom den arbetar med siffror. LowCardinality \u00e4r snabbare p\u00e5 grund av att det finns en optimering f\u00f6r GROUP BY. <\/p>\n<p><img decoding=\"async\" alt=\"Optimering av str\u00e4ngar i ClickHouse. Presentation fr\u00e5n Yandex\" src=\"\/wp-content\/uploads\/2020\/03\/e2ce4f2127d8728287488c85c92085fc.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nL\u00e5t oss komplicera fr\u00e5gan ytterligare \u2013 vi fr\u00e5gar var den mest popul\u00e4ra parken i New York ligger. \u00c5terigen kommer vi att m\u00e4ta detta p\u00e5 grundval av var taxin oftast best\u00e4lls, men filtrerar endast p\u00e5 de platser d\u00e4r det finns ordet \"park\". Vi l\u00e4gger ocks\u00e5 till funktionen like. <\/p>\n<p><img decoding=\"async\" alt=\"Optimering av str\u00e4ngar i ClickHouse. Presentation fr\u00e5n Yandex\" src=\"\/wp-content\/uploads\/2020\/03\/7cf6fd64751f3ae578581caddde17aaf.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nVi tittar p\u00e5 tiden \u2013 vi ser att Enum pl\u00f6tsligt b\u00f6rjade sl\u00e4pa efter. Det verkar till och med g\u00e5 l\u00e5ngsammare \u00e4n den vanliga datatypen String. Detta h\u00e4nder eftersom funktionen like inte \u00e4r optimerad f\u00f6r Enum. Vi m\u00e5ste omvandla v\u00e5ra str\u00e4ngar fr\u00e5n Enum till vanliga str\u00e4ngar \u2013 vi g\u00f6r mer arbete. LowCardinality(String) \u00e4r inte heller optimerad som standard, men d\u00e4r fungerar like p\u00e5 ordboken, s\u00e5 d\u00e4rf\u00f6r \u00e4r fr\u00e5gan snabbare i j\u00e4mf\u00f6relse med String. <\/p>\n<p>N\u00e4r man arbetar med Enum finns det ett mer globalt problem. Om vi vill optimera det m\u00e5ste vi g\u00f6ra det p\u00e5 varje st\u00e4lle i koden. L\u00e5t oss s\u00e4ga att vi har skrivit en ny funktion \u2013 vi m\u00e5ste absolut t\u00e4nka ut en optimering f\u00f6r Enum. Men i LowCardinality \u00e4r allt optimerat som standard.<\/p>\n<p><img decoding=\"async\" alt=\"Optimering av str\u00e4ngar i ClickHouse. Presentation fr\u00e5n Yandex\" src=\"\/wp-content\/uploads\/2020\/03\/459243eb5b3dd993393d0184b224ea09.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nL\u00e5t oss titta p\u00e5 den senaste fr\u00e5gan, som \u00e4r mer konstlad. Vi r\u00e4knar helt enkelt ut hash-funktionen av v\u00e5r plats. Hash-funktionen \u00e4r en ganska l\u00e5ngsam f\u00f6rfr\u00e5gan, den tar l\u00e5ng tid att ber\u00e4kna, d\u00e4rf\u00f6r kommer allt att sakta ner tre g\u00e5nger.<\/p>\n<p><img decoding=\"async\" alt=\"Optimering av str\u00e4ngar i ClickHouse. Presentation fr\u00e5n Yandex\" src=\"\/wp-content\/uploads\/2020\/03\/a5f49c22748971646ec358eb52d3feda.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nLowCardinality fungerar fortfarande snabbare, \u00e4ven om det inte finns n\u00e5gon filtrering h\u00e4r. Detta beror p\u00e5 att v\u00e5ra funktioner arbetar endast med ordboken. Hashber\u00e4kningsfunktionen har en parameter \u2013 den kan behandla mindre data och kan ocks\u00e5 returnera LowCardinality. <\/p>\n<p><img decoding=\"async\" alt=\"Optimering av str\u00e4ngar i ClickHouse. Presentation fr\u00e5n Yandex\" src=\"\/wp-content\/uploads\/2020\/03\/7842b7eb2debb4a4b1d4cbc3488deb32.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nV\u00e5r globala plan \u00e4r att uppn\u00e5 hastighet som inte \u00e4r l\u00e4gre \u00e4n f\u00f6r String i alla fall, och att beh\u00e5lla hastighets\u00f6kningarna. Och kanske kommer vi n\u00e5gon g\u00e5ng att ers\u00e4tta String med LowCardinality, du uppdaterar ClickHouse, och allt kommer att fungera lite snabbare.<br \/>\n<br \/>K\u00e4lla: <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/yandex\/blog\/492868\/\">habr.com<\/a> <\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>\u0410\u043d\u0430\u043b\u0438\u0442\u0438\u0447\u0435\u0441\u043a\u0430\u044f \u0421\u0423\u0411\u0414 ClickHouse \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u0442 \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u043e \u0440\u0430\u0437\u043d\u044b\u0445 \u0441\u0442\u0440\u043e\u043a, \u043f\u043e\u0442\u0440\u0435\u0431\u043b\u044f\u044f \u0440\u0435\u0441\u0443\u0440\u0441\u044b. \u0414\u043b\u044f \u0443\u0441\u043a\u043e\u0440\u0435\u043d\u0438\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441\u0438\u0441\u0442\u0435\u043c\u044b \u043f\u043e\u0441\u0442\u043e\u044f\u043d\u043d\u043e \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u043d\u043e\u0432\u044b\u0435 \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0430\u0446\u0438\u0438. \u0420\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a ClickHouse \u041d\u0438\u043a\u043e\u043b\u0430\u0439 \u041a\u043e\u0447\u0435\u0442\u043e\u0432 \u0440\u0430\u0441\u0441\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442 \u043e \u0441\u0442\u0440\u043e\u043a\u043e\u0432\u043e\u043c \u0442\u0438\u043f\u0435 \u0434\u0430\u043d\u043d\u044b\u0445, \u0432 \u0442\u043e\u043c \u0447\u0438\u0441\u043b\u0435 \u043e \u043d\u043e\u0432\u043e\u043c \u0442\u0438\u043f\u0435, LowCardinality, \u0438 \u043e\u0431\u044a\u044f\u0441\u043d\u044f\u0435\u0442, \u043a\u0430\u043a \u043c\u043e\u0436\u043d\u043e \u0443\u0441\u043a\u043e\u0440\u0438\u0442\u044c \u0440\u0430\u0431\u043e\u0442\u0443 \u0441\u043e \u0441\u0442\u0440\u043e\u043a\u0430\u043c\u0438. \u2014 \u0421\u043d\u0430\u0447\u0430\u043b\u0430 \u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u0440\u0430\u0437\u0431\u0435\u0440\u0435\u043c\u0441\u044f, \u043a\u0430\u043a \u043c\u043e\u0436\u043d\u043e \u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0441\u0442\u0440\u043e\u043a\u0438. \u0423 \u043d\u0430\u0441 \u0435\u0441\u0442\u044c \u0441\u0442\u0440\u043e\u043a\u043e\u0432\u044b\u0435 \u0442\u0438\u043f\u044b \u0434\u0430\u043d\u043d\u044b\u0445. [&hellip;]<\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"author":1,"featured_media":74738,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[688],"tags":[],"class_list":["post-74737","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-administrirovanie"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.4 - aioseo.com -->\n\t<meta name=\"description\" content=\"\u0410\u043d\u0430\u043b\u0438\u0442\u0438\u0447\u0435\u0441\u043a\u0430\u044f \u0421\u0423\u0411\u0414 ClickHouse \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u0442 \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u043e \u0440\u0430\u0437\u043d\u044b\u0445 \u0441\u0442\u0440\u043e\u043a, \u043f\u043e\u0442\u0440\u0435\u0431\u043b\u044f\u044f \u0440\u0435\u0441\u0443\u0440\u0441\u044b. \u0414\u043b\u044f \u0443\u0441\u043a\u043e\u0440\u0435\u043d\u0438\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441\u0438\u0441\u0442\u0435\u043c\u044b \u043f\u043e\u0441\u0442\u043e\u044f\u043d\u043d\u043e \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u043d\u043e\u0432\u044b\u0435 \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0430\u0446\u0438\u0438.\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"Yuri Gagarin\"\/>\n\t<link rel=\"canonical\" href=\"https:\/\/prohoster.info\/sv\/blog\/administrirovanie\/optimizacziya-strok-v-clickhouse-doklad-yandeksa\" \/>\n\t\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.4\" \/>\n\t\t<meta property=\"og:locale\" content=\"sv_SE\" \/>\n\t\t<meta property=\"og:site_name\" content=\"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"\ud83e\udd47\u041e\u043f\u0442\u0438\u043c\u0438\u0437\u0430\u0446\u0438\u044f \u0441\u0442\u0440\u043e\u043a \u0432 ClickHouse. \u0414\u043e\u043a\u043b\u0430\u0434 \u042f\u043d\u0434\u0435\u043a\u0441\u0430 | ProHoster\" \/>\n\t\t<meta property=\"og:description\" content=\"\u0410\u043d\u0430\u043b\u0438\u0442\u0438\u0447\u0435\u0441\u043a\u0430\u044f \u0421\u0423\u0411\u0414 ClickHouse \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u0442 \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u043e \u0440\u0430\u0437\u043d\u044b\u0445 \u0441\u0442\u0440\u043e\u043a, \u043f\u043e\u0442\u0440\u0435\u0431\u043b\u044f\u044f \u0440\u0435\u0441\u0443\u0440\u0441\u044b. \u0414\u043b\u044f \u0443\u0441\u043a\u043e\u0440\u0435\u043d\u0438\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441\u0438\u0441\u0442\u0435\u043c\u044b \u043f\u043e\u0441\u0442\u043e\u044f\u043d\u043d\u043e \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u043d\u043e\u0432\u044b\u0435 \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0430\u0446\u0438\u0438.\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/sv\/blog\/administrirovanie\/optimizacziya-strok-v-clickhouse-doklad-yandeksa\" \/>\n\t\t<meta property=\"og:image\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:secure_url\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:width\" content=\"350\" \/>\n\t\t<meta property=\"og:image:height\" content=\"350\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2020-03-20T05:43:14+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2020-03-20T05:43:14+00:00\" \/>\n\t\t<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<meta property=\"article:author\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"\ud83e\udd47Optimering av str\u00e4ngar i ClickHouse. Rapport fr\u00e5n Yandex | ProHoster","description":"Analytisk databas ClickHouse hanterar m\u00e5nga olika str\u00e4ngar och konsumerar resurser. F\u00f6r att snabba upp systemets arbete l\u00e4ggs kontinuerligt till nya optimeringar.","canonical_url":"https:\/\/prohoster.info\/sv\/blog\/administrirovanie\/optimizacziya-strok-v-clickhouse-doklad-yandeksa","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"sv_SE","og:site_name":"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b","og:type":"article","og:title":"\ud83e\udd47\u041e\u043f\u0442\u0438\u043c\u0438\u0437\u0430\u0446\u0438\u044f \u0441\u0442\u0440\u043e\u043a \u0432 ClickHouse. \u0414\u043e\u043a\u043b\u0430\u0434 \u042f\u043d\u0434\u0435\u043a\u0441\u0430 | ProHoster","og:description":"\u0410\u043d\u0430\u043b\u0438\u0442\u0438\u0447\u0435\u0441\u043a\u0430\u044f \u0421\u0423\u0411\u0414 ClickHouse \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u0442 \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u043e \u0440\u0430\u0437\u043d\u044b\u0445 \u0441\u0442\u0440\u043e\u043a, \u043f\u043e\u0442\u0440\u0435\u0431\u043b\u044f\u044f \u0440\u0435\u0441\u0443\u0440\u0441\u044b. \u0414\u043b\u044f \u0443\u0441\u043a\u043e\u0440\u0435\u043d\u0438\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441\u0438\u0441\u0442\u0435\u043c\u044b \u043f\u043e\u0441\u0442\u043e\u044f\u043d\u043d\u043e \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u043d\u043e\u0432\u044b\u0435 \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0430\u0446\u0438\u0438.","og:url":"https:\/\/prohoster.info\/sv\/blog\/administrirovanie\/optimizacziya-strok-v-clickhouse-doklad-yandeksa","og:image":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:secure_url":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:width":350,"og:image:height":350,"article:published_time":"2020-03-20T05:43:14+00:00","article:modified_time":"2020-03-20T05:43:14+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"74737","title":null,"description":null,"keywords":null,"keyphrases":null,"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":null,"og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"","isEnabled":true},"graphs":[]},"schema_type":null,"schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":null,"robots_max_videopreview":null,"robots_max_imagepreview":"large","priority":null,"frequency":null,"local_seo":null,"seo_analyzer_scan_date":null,"breadcrumb_settings":null,"limit_modified_date":false,"reviewed_by":null,"ai":null,"created":"2021-02-28 17:23:10","updated":"2022-09-27 14:48:44","focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"gt_translate_keys":[{"key":"link","format":"url"}],"_links":{"self":[{"href":"https:\/\/prohoster.info\/sv\/wp-json\/wp\/v2\/posts\/74737","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/sv\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/sv\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/sv\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/sv\/wp-json\/wp\/v2\/comments?post=74737"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/sv\/wp-json\/wp\/v2\/posts\/74737\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/sv\/wp-json\/wp\/v2\/media\/74738"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/sv\/wp-json\/wp\/v2\/media?parent=74737"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/sv\/wp-json\/wp\/v2\/categories?post=74737"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/sv\/wp-json\/wp\/v2\/tags?post=74737"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}