{"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\/de\/blog\/administrirovanie\/optimizacziya-strok-v-clickhouse-doklad-yandeksa","title":{"rendered":"Optimierung von Abfragen in ClickHouse. Vortrag von Yandex","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p>Die analytische Datenbank ClickHouse verarbeitet eine Vielzahl unterschiedlicher Zeichenfolgen und verbraucht dabei Ressourcen. Um die Systemleistung zu beschleunigen, werden st\u00e4ndig neue Optimierungen hinzugef\u00fcgt. Der Entwickler von ClickHouse, Nikolai Kochetov, spricht \u00fcber den Datentyp String, einschlie\u00dflich des neuen Typs LowCardinality, und erkl\u00e4rt, wie man die Arbeit mit Zeichenfolgen beschleunigen kann. <\/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=\"Video abspielen\" 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 Lassen Sie uns zun\u00e4chst kl\u00e4ren, wie Zeichenfolgen gespeichert werden k\u00f6nnen. <br \/>\n<noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><br \/>\n<img decoding=\"async\" alt=\"Optimierung von Abfragen in ClickHouse. Vortrag von Yandex\" src=\"\/wp-content\/uploads\/2020\/03\/5e38e903aaaf54a533bd3026e76a14be.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nWir verf\u00fcgen \u00fcber Datentypen f\u00fcr Zeichenfolgen. String eignet sich standardm\u00e4\u00dfig gut und sollte fast immer verwendet werden. Er hat einen geringen Overhead von 9 Byte pro Zeichenfolge. Wenn wir m\u00f6chten, dass die Gr\u00f6\u00dfe der Zeichenfolgen festgelegt und im Voraus bekannt ist, sollten wir besser FixedString verwenden. Hier k\u00f6nnen wir die gew\u00fcnschte Anzahl an Bytes festlegen, was f\u00fcr Daten wie IP-Adressen oder Hash-Funktionen praktisch ist. <\/p>\n<p><img decoding=\"async\" alt=\"Optimierung von Abfragen in ClickHouse. Vortrag von Yandex\" src=\"\/wp-content\/uploads\/2020\/03\/eaae898fb5163cb1c070c34a13f6f160.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nNat\u00fcrlich wird manchmal etwas langsamer. Angenommen, Sie stellen eine Anfrage an eine Tabelle. ClickHouse liest eine erhebliche Menge an Daten, sagen wir mit einer Geschwindigkeit von 100 GB\/s, w\u00e4hrend nur wenige Zeichenfolgen verarbeitet werden. Wir haben zwei Tabellen, die fast identische Daten speichern. Aus der zweiten Tabelle liest ClickHouse die Daten schneller, aber die Anzahl der pro Sekunde gelesenen Zeichenfolgen ist dreimal geringer. <\/p>\n<p><img decoding=\"async\" alt=\"Optimierung von Abfragen in ClickHouse. Vortrag von Yandex\" src=\"\/wp-content\/uploads\/2020\/03\/be7cc47e628112bb212ed0e8ff9091ed.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nWenn wir die Gr\u00f6\u00dfe der komprimierten Daten betrachten, wird sie fast gleich sein. Tats\u00e4chlich sind in den Tabellen die gleichen Daten gespeichert \u2014 die erste Milliarde Zahlen \u2014 nur im ersten Datenfeld sind sie als UInt64 gespeichert, im zweiten als String. Aus diesem Grund ben\u00f6tigt die zweite Anfrage l\u00e4nger, um die Daten von der Festplatte zu lesen und sie zu dekomprimieren. <\/p>\n<p><img decoding=\"async\" alt=\"Optimierung von Abfragen in ClickHouse. Vortrag von Yandex\" src=\"\/wp-content\/uploads\/2020\/03\/c699103cecd972fcee73841cc35716d6.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nHier ein weiteres Beispiel. Angenommen, es gibt eine vorher bekannte Menge von Zeichenfolgen, die durch eine Konstante von 1000 oder 10.000 beschr\u00e4nkt und so gut wie nie ver\u00e4ndert wird. F\u00fcr diesen Fall eignet sich der Datentyp Enum, von dem es in ClickHouse zwei gibt \u2014 Enum8 und Enum16. Durch die Speicherung in Enum k\u00f6nnen wir Anfragen schnell verarbeiten. <\/p>\n<p>In ClickHouse gibt es Beschleunigungen f\u00fcr GROUP BY, IN, DISTINCT und Optimierungen f\u00fcr einige Funktionen, zum Beispiel f\u00fcr den Vergleich mit einer konstanten Zeichenfolge. Nat\u00fcrlich werden Zahlen in Zeichenfolgen nicht umgewandelt, sondern im Gegenteil, die konstante Zeichenfolge wird in den Wert Enum umgewandelt. Danach erfolgt der Vergleich schnell. <\/p>\n<p>Es gibt jedoch auch Nachteile. Selbst wenn wir die genaue Menge an Zeichenfolgen kennen, muss sie manchmal erweitert werden. Eine neue Zeichenfolge ist eingetroffen \u2014 wir m\u00fcssen ein ALTER durchf\u00fchren. <\/p>\n<p><img decoding=\"async\" alt=\"Optimierung von Abfragen in ClickHouse. Vortrag von Yandex\" src=\"\/wp-content\/uploads\/2020\/03\/064c35faaf3d9de2f12d29f83197e983.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nALTER f\u00fcr Enum in ClickHouse ist optimal umgesetzt. Wir schreiben die Daten auf der Festplatte nicht neu, aber ALTER kann wegen der Tatsache, dass die Enum-Strukturen im Schema der Tabelle gespeichert sind, etwas langsam sein. Daher m\u00fcssen wir auf Leseanforderungen aus der Tabelle warten, zum Beispiel. <\/p>\n<p>Die Frage stellt sich, ob man es besser machen kann? Wahrscheinlich ja. Man k\u00f6nnte die Enum-Struktur nicht im Tabellenschema, sondern in ZooKeeper speichern. Allerdings k\u00f6nnten Synchronisationsprobleme auftreten. Zum Beispiel, wenn eine Replik Daten erh\u00e4lt, die andere nicht, und wenn sie dann ein altes Enum hat, k\u00f6nnte etwas kaputtgehen. (In ClickHouse haben wir fast die nicht-blockierenden ALTER-Abfragen fertiggestellt. Wenn wir sie vollst\u00e4ndig abschlie\u00dfen, m\u00fcssen wir nicht mehr auf Leseanforderungen warten.)<\/p>\n<p><img decoding=\"async\" alt=\"Optimierung von Abfragen in ClickHouse. Vortrag von Yandex\" src=\"\/wp-content\/uploads\/2020\/03\/f5d2fdf14778f6afdd4acc8c204e163c.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nUm sich mit ALTER Enum nicht herumzuschlagen, kann man externe Dictionaries von ClickHouse verwenden. Ich erinnere daran, dass dies eine Key-Value-Datenstruktur innerhalb von ClickHouse ist, mit der man Daten aus externen Quellen abrufen kann, beispielsweise von MySQL-Tabellen. <\/p>\n<p>Im Dictionary von ClickHouse speichern wir viele verschiedene Strings, und in der Tabelle sind ihre Identifikatoren in Form von Zahlen. Wenn wir einen String ben\u00f6tigen, rufen wir die Funktion dictGet auf und arbeiten mit ihr. Danach m\u00fcssen wir kein ALTER durchf\u00fchren. Um etwas dem Enum hinzuzuf\u00fcgen, f\u00fcgen wir es in die gleiche MySQL-Tabelle ein. <\/p>\n<p>Aber hier entstehen andere Probleme. Erstens die umst\u00e4ndliche Syntax. Wenn wir einen String erhalten m\u00f6chten, m\u00fcssen wir dictGet aufrufen. Zweitens das Fehlen bestimmter Optimierungen. Der Vergleich mit einem konstanten String ist f\u00fcr Dictionaries nicht so schnell m\u00f6glich. <\/p>\n<p>Es k\u00f6nnen auch Probleme mit Updates auftreten. Angenommen, wir haben einen String im Cache-Dictionary angefordert, aber er ist nicht im Cache gelandet. Dann m\u00fcssen wir warten, bis die Daten aus der externen Quelle geladen werden. <\/p>\n<p><img decoding=\"async\" alt=\"Optimierung von Abfragen in ClickHouse. Vortrag von Yandex\" src=\"\/wp-content\/uploads\/2020\/03\/534818ee523a243623a5cb2babe08040.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nEin allgemeines Manko beider Methoden ist, dass wir alle Schl\u00fcssel an einem Ort speichern und sie synchronisieren. Warum nicht die Dictionaries lokal speichern? Keine Synchronisation \u2013 keine Probleme. Man kann das Dictionary lokal auf einem St\u00fcck der Festplatte speichern. Das hei\u00dft, wir haben ein Insert durchgef\u00fchrt, das Dictionary aufgezeichnet. Wenn wir mit Daten im Arbeitsspeicher arbeiten, k\u00f6nnen wir das Dictionary entweder in einen Datenblock, in ein St\u00fcck der Spalte oder in einen Cache speichern, um die Berechnungen zu beschleunigen.<\/p>\n<h3>Dictionary-Codierung von Strings <\/h3>\n<p>\nSo sind wir zur Schaffung eines neuen Datentyps in ClickHouse \u2013 LowCardinality \u2013 gekommen. Dies ist ein Datenformat: wie sie auf der Festplatte geschrieben und gelesen werden, wie sie im Speicher dargestellt werden und wie ihr Verarbeitungschema aussieht. <\/p>\n<p><img decoding=\"async\" alt=\"Optimierung von Abfragen in ClickHouse. Vortrag von Yandex\" src=\"\/wp-content\/uploads\/2020\/03\/e25b2eb12ff158b89b7d2dbdfb8e2e5a.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nAuf der Folie gibt es zwei Spalten. Rechts werden die Zeilen standardm\u00e4\u00dfig im Typ String gespeichert. Man sieht, dass dies einige Modelle von Mobiltelefonen sind. Links gibt es genau die gleiche Spalte, nur im Typ LowCardinality. Sie besteht aus einem W\u00f6rterbuch mit vielen verschiedenen Zeilen (Zeilen aus der rechten Spalte) und einer Liste von Positionen (Zeilennummern). <\/p>\n<p>Mit diesen beiden Strukturen kann man die urspr\u00fcngliche Spalte wiederherstellen. Es gibt auch einen umgekehrten Index \u2013 eine Hash-Tabelle, die hilft, die Position im W\u00f6rterbuch anhand der Zeile zu finden. Diese ist notwendig, um bestimmte Abfragen zu beschleunigen. Zum Beispiel, wenn wir eine Zeile in unserer Spalte vergleichen oder suchen m\u00f6chten oder sie zusammenf\u00fchren wollen. <\/p>\n<p>LowCardinality ist ein parametrischer Datentyp. Er kann entweder eine Zahl sein, oder etwas, das als Zahl gespeichert wird, oder ein String, oder Nullable davon. <\/p>\n<p><img decoding=\"async\" alt=\"Optimierung von Abfragen in ClickHouse. Vortrag von Yandex\" src=\"\/wp-content\/uploads\/2020\/03\/d52ef0c99617238442d4f71e43af48af.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nDas Besondere an LowCardinality ist, dass es f\u00fcr einige Funktionen gespeichert werden kann. Auf der Folie sieht man ein Beispiel f\u00fcr eine Abfrage. In der ersten Zeile habe ich eine Spalte vom Typ LowCardinality von String erstellt und sie S genannt. Dann fragte ich nach ihrem Namen \u2013 ClickHouse sagte, dass es LowCardinality von String ist. Alles richtig.<\/p>\n<p>Die dritte Zeile ist fast identisch, nur dass wir die Funktion length aufgerufen haben. In ClickHouse gibt die Funktion length den Datentyp UInt64 zur\u00fcck. Aber wir haben jetzt LowCardinality von UInt64. Was ist der Sinn?<\/p>\n<p><img decoding=\"async\" alt=\"Optimierung von Abfragen in ClickHouse. Vortrag von Yandex\" src=\"\/wp-content\/uploads\/2020\/03\/a4a51a0f1ecd68f7fffd521ab786c8a5.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nIm W\u00f6rterbuch wurden die Namen von Mobiltelefonen gespeichert, wir haben die Funktion length angewendet. Jetzt haben wir ein \u00e4hnliches W\u00f6rterbuch, das nur aus Zahlen besteht \u2013 das sind die L\u00e4ngen der Strings. Die Spalte mit den Positionen hat sich nicht ge\u00e4ndert. Insgesamt haben wir weniger Daten verarbeitet und Zeit bei der Abfrage gespart. <\/p>\n<p>Es kann auch andere Optimierungen geben, wie zum Beispiel die Hinzuf\u00fcgung eines einfachen Caches. Bei der Berechnung des Wertes einer Funktion kann man diesen speichern und denselben Wert erneut erstellen, ohne neu zu berechnen. <\/p>\n<p>Es kann auch eine Optimierung von GROUP BY vorgenommen werden, da unsere Spalte mit dem W\u00f6rterbuch bereits teilweise aggregiert ist \u2013 dadurch k\u00f6nnen die Werte der Hash-Funktionen schneller berechnet und die ungef\u00e4hr passende Bucket gefunden werden, in die die n\u00e4chste Zeile eingef\u00fcgt werden kann. Au\u00dferdem kann man bestimmte Aggregatfunktionen spezialisieren, zum Beispiel uniq, da man nur das W\u00f6rterbuch senden kann und die Positionen unber\u00fchrt l\u00e4sst \u2013 so wird alles schneller funktionieren. Die ersten beiden Optimierungen haben wir bereits in ClickHouse hinzugef\u00fcgt.<\/p>\n<p><img decoding=\"async\" alt=\"Optimierung von Abfragen in ClickHouse. Vortrag von Yandex\" src=\"\/wp-content\/uploads\/2020\/03\/943e0a8ae5a37cd47164246db3a67893.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nWas aber, wenn wir eine Spalte mit unserem Datentyp erstellen und darin viele verschiedene, schlechte Zeilen einf\u00fcgen? Wird unser Speicher \u00fcberlaufen? Nein, daf\u00fcr gibt es in ClickHouse zwei spezielle Einstellungen. Die erste ist low_cardinality_max_dictionary_size. Das ist die maximale Gr\u00f6\u00dfe des W\u00f6rterbuchs, das auf die Festplatte geschrieben werden kann. Das Einf\u00fcgen erfolgt folgenderma\u00dfen: Wenn wir Daten einf\u00fcgen, erhalten wir einen Strom von Zeilen, aus denen wir ein gro\u00dfes gemeinsames W\u00f6rterbuch erstellen. Wenn das W\u00f6rterbuch gr\u00f6\u00dfer wird als der Wert der Einstellung, schreiben wir das aktuelle W\u00f6rterbuch auf die Festplatte, und die restlichen Zeilen werden irgendwo \u201enebenbei\u201c, neben den Indizes, gespeichert. Am Ende werden wir also niemals das gro\u00dfe W\u00f6rterbuch neu z\u00e4hlen und haben keine Probleme mit dem Speicher. <\/p>\n<p>Die zweite Einstellung wird low_cardinality_use_single_dictionary_for_part genannt. Stellen Sie sich vor, dass in dem vorherigen Schema, als wir Daten eingef\u00fcgt haben, unser W\u00f6rterbuch \u00fcbergelaufen ist und wir es auf die Festplatte geschrieben haben. Die Frage ist nun, warum wir nicht ein weiteres genau gleiches W\u00f6rterbuch erstellen sollten? <\/p>\n<p>Wenn es \u00fcberl\u00e4uft, schreiben wir es wieder auf die Festplatte und beginnen, das dritte zu erstellen. Diese Einstellung deaktiviert genau diese M\u00f6glichkeit standardm\u00e4\u00dfig. <\/p>\n<p>In der Tat k\u00f6nnen viele W\u00f6rterb\u00fccher n\u00fctzlich sein, wenn wir eine bestimmte Menge an Zeilen einf\u00fcgen wollen, aber versehentlich \u201eM\u00fcll\u201c eingef\u00fcgt haben. Sagen wir, zuerst haben wir schlechte Zeilen eingef\u00fcgt, und dann gute. Dann wird das W\u00f6rterbuch in viele kleine W\u00f6rterb\u00fccher aufgeteilt. Einige von ihnen enthalten \u201eM\u00fcll\u201c, aber die letzten werden mit guten Zeilen gef\u00fcllt sein. Und wenn wir nur das letzte Granulat lesen, wird auch alles schnell funktionieren. <\/p>\n<p><img decoding=\"async\" alt=\"Optimierung von Abfragen in ClickHouse. Vortrag von Yandex\" src=\"\/wp-content\/uploads\/2020\/03\/834ba3295ace98870334aa10a78e4781.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nBevor ich \u00fcber die Vorteile von LowCardinality spreche, sage ich gleich, dass wir wahrscheinlich keine Reduzierung der Daten auf der Festplatte erreichen werden (obwohl das geschehen kann), da ClickHouse die Daten komprimiert. Es gibt eine Standardoption - LZ4. Man kann auch die Komprimierung mit ZSTD vornehmen. Aber beide Algorithmen implementieren bereits die W\u00f6rterbuchkompression, weshalb unser externes W\u00f6rterbuch in ClickHouse nicht besonders hilfreich ist. <\/p>\n<p>Um nicht unbegr\u00fcndet zu sein, habe ich einige Daten aus der Metrik entnommen \u2014 String, LowCardinality(String) und Enum \u2014 und sie in verschiedene Datentypen gespeichert. Es entstanden drei Spalten, in denen eine Milliarde Zeilen verzeichnet sind. In der ersten Spalte, CodePage, gibt es insgesamt 62 Werte. Man sieht, dass wir sie in LowCardinality(String) besser komprimiert haben. String ist ein wenig schlechter, aber das liegt wahrscheinlich daran, dass die Strings kurz sind, wir ihre L\u00e4ngen speichern und sie viel Platz einnehmen, schlecht komprimiert werden. <\/p>\n<p>Wenn man PhoneModel betrachtet, gibt es 48.000 \u2014 schon mehr, und die Unterschiede zwischen String und LowCardinality(String) sind fast nicht vorhanden. Bei URL haben wir ebenfalls nur 2 GB gespart \u2014 ich denke, darauf sollte man sich nicht verlassen. <\/p>\n<h3>Bewertung der Arbeitsgeschwindigkeit<\/h3>\n<p>\n<img decoding=\"async\" alt=\"Optimierung von Abfragen in ClickHouse. Vortrag von 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\">Link zur Folie<\/a><\/noindex><\/b><\/p>\n<p>Jetzt bewerten wir die Arbeitsgeschwindigkeit. Um dies zu bewerten, habe ich ein Dataset mit Beschreibungen von Taxifahrten in New York verwendet. Es enth\u00e4lt <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/toddwschneider\/nyc-taxi-data\">verf\u00fcgbar<\/a><\/noindex> auf GitHub. Darin sind etwas mehr als eine Milliarde Fahrten enthalten. Es sind der Standort, die Start- und Endzeit der Fahrt, die Zahlungsart, die Anzahl der Passagiere und sogar die Art des Taxis \u2014 gr\u00fcn, gelb und Uber \u2014 aufgef\u00fchrt. <\/p>\n<p><img decoding=\"async\" alt=\"Optimierung von Abfragen in ClickHouse. Vortrag von Yandex\" src=\"\/wp-content\/uploads\/2020\/03\/0901669dec01b0f956d6976e3aa8b741.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nDie erste Abfrage habe ich recht einfach gehalten \u2014 ich habe gefragt, wo am h\u00e4ufigsten Taxis bestellt werden. Dazu muss man den Standort nehmen, von dem aus bestellt wurde, eine GROUP BY-Abfrage erstellen und die Funktion count z\u00e4hlen. So liefert ClickHouse etwas. <\/p>\n<p><img decoding=\"async\" alt=\"Optimierung von Abfragen in ClickHouse. Vortrag von Yandex\" src=\"\/wp-content\/uploads\/2020\/03\/50983341e20bcbc1b5adbaed35f8624d.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nUm die Geschwindigkeit der Abfrage zu messen, habe ich drei Tabellen mit denselben Daten erstellt, aber f\u00fcr unseren Startstandort drei verschiedene Datentypen verwendet \u2014 String, LowCardinality und Enum. LowCardinality und Enum waren f\u00fcnfmal schneller als String. Enum ist schneller, weil es mit Zahlen arbeitet. LowCardinality ist schneller, weil es eine GROUP BY-Optimierung implementiert. <\/p>\n<p><img decoding=\"async\" alt=\"Optimierung von Abfragen in ClickHouse. Vortrag von Yandex\" src=\"\/wp-content\/uploads\/2020\/03\/e2ce4f2127d8728287488c85c92085fc.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nLassen Sie uns die Abfrage noch komplizierter gestalten \u2014 fragen wir, wo sich der beliebteste Park in New York befindet. Auch hier werden wir messen, wo am h\u00e4ufigsten Taxis bestellt werden, aber wir filtern nur die Standorte, die das Wort \u201ePark\u201c enthalten. Zus\u00e4tzlich f\u00fcgen wir die Funktion like hinzu. <\/p>\n<p><img decoding=\"async\" alt=\"Optimierung von Abfragen in ClickHouse. Vortrag von Yandex\" src=\"\/wp-content\/uploads\/2020\/03\/7cf6fd64751f3ae578581caddde17aaf.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nWir schauen auf die Zeit \u2014 sehen, dass Enum pl\u00f6tzlich anf\u00e4ngt langsam zu werden. Tats\u00e4chlich arbeitet er sogar langsamer als der Standarddatentyp String. Das geschieht, weil die Funktion like f\u00fcr Enum \u00fcberhaupt nicht optimiert ist. Wir m\u00fcssen unsere Strings von Enum in normale Strings umwandeln \u2014 wir machen mehr Arbeit. LowCardinality(String) ist ebenfalls nicht standardm\u00e4\u00dfig optimiert, aber dort funktioniert like \u00fcber das W\u00f6rterbuch, weshalb die Abfrage im Vergleich zu String beschleunigt wird. <\/p>\n<p>Bei der Arbeit mit Enum gibt es ein gr\u00f6\u00dferes Problem. Wenn wir es optimieren m\u00f6chten, m\u00fcssen wir dies an jedem Ort im Code tun. Angenommen, wir haben eine neue Funktion geschrieben \u2013 dann m\u00fcssen wir unbedingt eine Optimierung f\u00fcr Enum erfinden. Und bei LowCardinality ist alles standardm\u00e4\u00dfig optimiert.<\/p>\n<p><img decoding=\"async\" alt=\"Optimierung von Abfragen in ClickHouse. Vortrag von Yandex\" src=\"\/wp-content\/uploads\/2020\/03\/459243eb5b3dd993393d0184b224ea09.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nSchauen wir uns die letzte Abfrage an, die k\u00fcnstlicher ist. Wir berechnen einfach die Hash-Funktion unseres Standorts. Die Hash-Funktion ist eine ziemlich langsame Abfrage, sie dauert lange, daher wird alles um den Faktor drei langsamer.<\/p>\n<p><img decoding=\"async\" alt=\"Optimierung von Abfragen in ClickHouse. Vortrag von Yandex\" src=\"\/wp-content\/uploads\/2020\/03\/a5f49c22748971646ec358eb52d3feda.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nLowCardinality arbeitet immer noch schneller, obwohl es hier keine Filterung gibt. Das liegt daran, dass unsere Funktionen nur \u00fcber das W\u00f6rterbuch arbeiten. Die Hash-Berechnungsfunktion hat ein Argument \u2013 sie kann weniger Daten verarbeiten und kann auch LowCardinality zur\u00fcckgeben. <\/p>\n<p><img decoding=\"async\" alt=\"Optimierung von Abfragen in ClickHouse. Vortrag von Yandex\" src=\"\/wp-content\/uploads\/2020\/03\/7842b7eb2debb4a4b1d4cbc3488deb32.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nUnser globaler Plan ist es, eine Arbeitsgeschwindigkeit zu erreichen, die in allen F\u00e4llen nicht unter der von String liegt, und die Beschleunigung beizubehalten. Und vielleicht ersetzen wir eines Tages String durch LowCardinality, Sie aktualisieren ClickHouse, und alles funktioniert ein wenig schneller.<br \/>\n<br \/>Quelle: <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.1.1 - 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\/de\/blog\/administrirovanie\/optimizacziya-strok-v-clickhouse-doklad-yandeksa\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.1.1\" \/>\n\t\t<meta property=\"og:locale\" content=\"de_DE\" \/>\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\/de\/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\udd47Optimierung von Zeichenfolgen in ClickHouse. Bericht von Yandex | ProHoster","description":"Das analytische DBMS ClickHouse verarbeitet eine Vielzahl von verschiedenen Zeichenfolgen und verbraucht Ressourcen. Um die Systemgeschwindigkeit zu erh\u00f6hen, werden st\u00e4ndig neue Optimierungen hinzugef\u00fcgt.","canonical_url":"https:\/\/prohoster.info\/de\/blog\/administrirovanie\/optimizacziya-strok-v-clickhouse-doklad-yandeksa","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"de_DE","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\/de\/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\/de\/wp-json\/wp\/v2\/posts\/74737","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/comments?post=74737"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/posts\/74737\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/media\/74738"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/media?parent=74737"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/categories?post=74737"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/tags?post=74737"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}