{"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\/es\/blog\/administrirovanie\/optimizacziya-strok-v-clickhouse-doklad-yandeksa","title":{"rendered":"Optimizaci\u00f3n de cadenas en ClickHouse. Informe de Yandex","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p>La base de datos anal\u00edtica ClickHouse procesa una gran variedad de cadenas, consumiendo recursos. Para agilizar el funcionamiento del sistema, se a\u00f1aden constantemente nuevas optimizaciones. El desarrollador de ClickHouse, Nikolai Kochetov, habla sobre el tipo de datos de cadena, incluido el nuevo tipo, LowCardinality, y explica c\u00f3mo se puede acelerar el trabajo con cadenas. <\/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=\"Reproducir 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 Primero, analicemos c\u00f3mo se pueden almacenar las cadenas. <br \/>\n<noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><br \/>\n<img decoding=\"async\" alt=\"Optimizaci\u00f3n de cadenas en ClickHouse. Informe de Yandex\" src=\"\/wp-content\/uploads\/2020\/03\/5e38e903aaaf54a533bd3026e76a14be.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nContamos con tipos de datos de cadena. String es adecuado por defecto y deber\u00eda usarse casi siempre. Tiene baja sobrecarga: 9 bytes por cada cadena. Si queremos que el tama\u00f1o de las cadenas sea fijo y conocido de antemano, es mejor utilizar FixedString. En \u00e9l, se puede especificar la cantidad de bytes que necesitamos, lo cual es conveniente para datos como direcciones IP o funciones hash. <\/p>\n<p><img decoding=\"async\" alt=\"Optimizaci\u00f3n de cadenas en ClickHouse. Informe de Yandex\" src=\"\/wp-content\/uploads\/2020\/03\/eaae898fb5163cb1c070c34a13f6f160.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nPor supuesto, a veces algo puede ralentizarse. Supongamos que est\u00e1s haciendo una consulta a una tabla. ClickHouse lee una cantidad bastante grande de datos, digamos, a una velocidad de 100 GB\/s, mientras que se procesan pocas cadenas. Tenemos dos tablas que almacenan datos casi id\u00e9nticos. Desde la segunda tabla, ClickHouse lee datos a una velocidad mayor, pero se leen tres veces menos cadenas por segundo. <\/p>\n<p><img decoding=\"async\" alt=\"Optimizaci\u00f3n de cadenas en ClickHouse. Informe de Yandex\" src=\"\/wp-content\/uploads\/2020\/03\/be7cc47e628112bb212ed0e8ff9091ed.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nSi observamos el tama\u00f1o de los datos comprimidos, resultar\u00e1 ser casi equivalente. De hecho, las tablas contienen los mismos datos: el primer mil millones de n\u00fameros, solo que en la primera columna se almacenan como UInt64 y en la segunda como String. Debido a esto, la segunda consulta tarda m\u00e1s en leer los datos del disco y descomprimirlos. <\/p>\n<p><img decoding=\"async\" alt=\"Optimizaci\u00f3n de cadenas en ClickHouse. Informe de Yandex\" src=\"\/wp-content\/uploads\/2020\/03\/c699103cecd972fcee73841cc35716d6.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nAqu\u00ed hay otro ejemplo. Supongamos que hay un conjunto de cadenas conocido de antemano, limitado a una constante de 1000 o 10,000 y que pr\u00e1cticamente nunca cambia. Para este caso, el tipo de datos Enum es adecuado, ya que ClickHouse tiene dos: Enum8 y Enum16. Al almacenar en Enum, procesamos las consultas r\u00e1pidamente. <\/p>\n<p>En ClickHouse hay optimizaciones para GROUP BY, IN, DISTINCT y mejoras para algunas funciones, como la comparaci\u00f3n con una cadena constante. Por supuesto, los n\u00fameros en la cadena no se transforman y, al contrario, la cadena constante se convierte en un valor Enum. Despu\u00e9s de eso, todo se compara r\u00e1pidamente. <\/p>\n<p>Pero tambi\u00e9n hay desventajas. Incluso si conocemos el conjunto exacto de cadenas, a veces debe ampliarse. Si llega una nueva cadena, debemos hacer ALTER. <\/p>\n<p><img decoding=\"async\" alt=\"Optimizaci\u00f3n de cadenas en ClickHouse. Informe de Yandex\" src=\"\/wp-content\/uploads\/2020\/03\/064c35faaf3d9de2f12d29f83197e983.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nEl comando ALTER para Enum en ClickHouse est\u00e1 optimizado. No reescribimos datos en el disco, pero ALTER puede experimentar lentitud debido a que las estructuras Enum se almacenan en el esquema de la tabla misma. Por lo tanto, debemos esperar las consultas de lectura de la tabla, por ejemplo. <\/p>\n<p>Surge la pregunta, \u00bfse puede hacer mejor? Probablemente s\u00ed. Se podr\u00eda almacenar la estructura Enum no en el esquema de la tabla, sino en ZooKeeper. Sin embargo, pueden surgir problemas relacionados con la sincronizaci\u00f3n. Por ejemplo, una r\u00e9plica tiene los datos, la otra no, y si tiene un Enum antiguo, algo puede romperse. (En ClickHouse hemos casi terminado las consultas ALTER no bloqueantes. Cuando las terminemos por completo, no ser\u00e1 necesario esperar a las consultas de lectura.)<\/p>\n<p><img decoding=\"async\" alt=\"Optimizaci\u00f3n de cadenas en ClickHouse. Informe de Yandex\" src=\"\/wp-content\/uploads\/2020\/03\/f5d2fdf14778f6afdd4acc8c204e163c.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nPara evitar lidiar con ALTER Enum, se pueden utilizar diccionarios externos de ClickHouse. Recuerdo que esta es una estructura de datos clave-valor dentro de ClickHouse, a trav\u00e9s de la cual se pueden obtener datos de fuentes externas, como tablas MySQL. <\/p>\n<p>En el diccionario de ClickHouse almacenamos muchas cadenas diferentes, y en la tabla, sus identificadores en forma de n\u00fameros. Si necesitamos obtener una cadena, llamamos a la funci\u00f3n dictGet y trabajamos con ella. Despu\u00e9s de eso, no necesitamos hacer ALTER. Para agregar algo a Enum, lo insertamos en la misma tabla de MySQL. <\/p>\n<p>Pero aqu\u00ed surgen otros problemas. Primero, la sintaxis inc\u00f3moda. Si queremos obtener una cadena, debemos llamar a dictGet. En segundo lugar, falta algunas optimizaciones. La comparaci\u00f3n con una cadena constante para los diccionarios no se puede hacer tan r\u00e1pidamente. <\/p>\n<p>Tambi\u00e9n pueden haber problemas con la actualizaci\u00f3n. Supongamos que solicitamos una cadena en un diccionario en cach\u00e9, pero no lleg\u00f3 a la cach\u00e9. Entonces debemos esperar hasta que se carguen los datos de la fuente externa. <\/p>\n<p><img decoding=\"async\" alt=\"Optimizaci\u00f3n de cadenas en ClickHouse. Informe de Yandex\" src=\"\/wp-content\/uploads\/2020\/03\/534818ee523a243623a5cb2babe08040.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nLa desventaja com\u00fan de ambos m\u00e9todos es que almacenamos todas las claves en un solo lugar y las sincronizamos. Entonces, \u00bfpor qu\u00e9 no almacenar los diccionarios localmente? Sin sincronizaci\u00f3n, no hay problemas. Se puede almacenar un diccionario localmente en un trozo en el disco. Es decir, hicimos un Insert, grabamos el diccionario. Si trabajamos con datos en memoria, podemos almacenar el diccionario ya sea en un bloque de datos, o en un fragmento de columna, o en alg\u00fan cach\u00e9, para acelerar los c\u00e1lculos.<\/p>\n<h3>Codificaci\u00f3n de cadenas por diccionario <\/h3>\n<p>\nAs\u00ed llegamos a la creaci\u00f3n de un nuevo tipo de datos en ClickHouse \u2014 LowCardinality. Este es un formato de almacenamiento de datos: c\u00f3mo se escriben en disco y c\u00f3mo se leen, c\u00f3mo se representan en memoria y el esquema de su procesamiento. <\/p>\n<p><img decoding=\"async\" alt=\"Optimizaci\u00f3n de cadenas en ClickHouse. Informe de Yandex\" src=\"\/wp-content\/uploads\/2020\/03\/e25b2eb12ff158b89b7d2dbdfb8e2e5a.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nEn la diapositiva hay dos columnas. A la derecha, las filas se almacenan de manera est\u00e1ndar, en el tipo String. Se puede ver que son modelos de tel\u00e9fonos m\u00f3viles. A la izquierda hay una columna exactamente igual, pero en el tipo LowCardinality. Consiste en un diccionario con muchas cadenas diferentes (cadenas de la columna de la derecha) y una lista de posiciones (n\u00fameros de fila). <\/p>\n<p>Con estas dos estructuras se puede reconstruir la columna original. Tambi\u00e9n hay un \u00edndice inverso, una tabla hash que ayuda a encontrar la posici\u00f3n en el diccionario a partir de la cadena. Se necesita para acelerar algunas consultas. Por ejemplo, si queremos comparar, buscar una cadena en nuestra columna o fusionarlas. <\/p>\n<p>LowCardinality es un tipo de dato param\u00e9trico. Puede ser un n\u00famero, o algo que se almacena como un n\u00famero, o una cadena, o Nullable de estos. <\/p>\n<p><img decoding=\"async\" alt=\"Optimizaci\u00f3n de cadenas en ClickHouse. Informe de Yandex\" src=\"\/wp-content\/uploads\/2020\/03\/d52ef0c99617238442d4f71e43af48af.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nLa peculiaridad de LowCardinality es que puede almacenarse para algunas funciones. En la diapositiva se ve un ejemplo de consulta. En la primera l\u00ednea, cre\u00e9 una columna del tipo LowCardinality de String y la llam\u00e9 S. Luego pregunt\u00e9 su nombre; ClickHouse dijo que era LowCardinality de String. Todo correcto.<\/p>\n<p>La tercera l\u00ednea es casi igual, solo que llamamos a la funci\u00f3n length. En ClickHouse, la funci\u00f3n length devuelve el tipo de dato UInt64. Pero ahora se convirti\u00f3 en LowCardinality de UInt64. \u00bfCu\u00e1l es el sentido?<\/p>\n<p><img decoding=\"async\" alt=\"Optimizaci\u00f3n de cadenas en ClickHouse. Informe de Yandex\" src=\"\/wp-content\/uploads\/2020\/03\/a4a51a0f1ecd68f7fffd521ab786c8a5.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nEn el diccionario se almacenaban los nombres de tel\u00e9fonos m\u00f3viles; aplicamos la funci\u00f3n length. Ahora tenemos un diccionario equivalente, compuesto solo de n\u00fameros, que son las longitudes de las cadenas. La columna con posiciones no cambi\u00f3. Al final, procesamos menos datos, ahorramos tiempo de consulta. <\/p>\n<p>Puede haber otras optimizaciones, como el agregado de una cach\u00e9 simple. Al calcular el valor de una funci\u00f3n, se puede recordar y crear uno igual, sin necesidad de recalcularlo. <\/p>\n<p>Tambi\u00e9n se puede optimizar el GROUP BY, porque nuestra columna con el diccionario ya est\u00e1 parcialmente agregada: se pueden calcular m\u00e1s r\u00e1pidamente los valores de las funciones hash y encontrar aproximadamente el bucket donde colocar la siguiente fila. Adem\u00e1s, se pueden especializar algunas funciones agregadas, como uniq, ya que solo se puede enviar un diccionario y dejar las posiciones intactas; as\u00ed todo funcionar\u00e1 m\u00e1s r\u00e1pido. Ya hemos agregado las dos primeras optimizaciones en ClickHouse.<\/p>\n<p><img decoding=\"async\" alt=\"Optimizaci\u00f3n de cadenas en ClickHouse. Informe de Yandex\" src=\"\/wp-content\/uploads\/2020\/03\/943e0a8ae5a37cd47164246db3a67893.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\n\u00bfY si creamos una columna con nuestro tipo de datos e insertamos muchas cadenas incorrectas diferentes? \u00bfNo se desbordar\u00e1 nuestra memoria? No, para eso ClickHouse tiene dos configuraciones especiales. La primera es low_cardinality_max_dictionary_size. Este es el tama\u00f1o m\u00e1ximo del diccionario que se puede escribir en el disco. La inserci\u00f3n ocurre de la siguiente manera: cuando insertamos datos, recibimos un flujo de cadenas, de las cuales formamos un gran diccionario com\u00fan. Si el diccionario se vuelve m\u00e1s grande que el valor de la configuraci\u00f3n, escribimos el diccionario actual en el disco, y las otras cadenas las dejamos \u201ca un lado\u201d, junto a los \u00edndices. Como resultado, nunca volveremos a contar el gran diccionario y no tendremos problemas de memoria. <\/p>\n<p>La segunda configuraci\u00f3n se llama low_cardinality_use_single_dictionary_for_part. Imagina que en el esquema anterior, cuando insertamos los datos, nuestro diccionario se desbord\u00f3 y lo escribimos en el disco. Surge la pregunta, \u00bfpor qu\u00e9 no formar ahora otro diccionario exactamente igual? <\/p>\n<p>Cuando se desborde, lo escribiremos de nuevo en el disco y comenzaremos a formar el tercero. Esta configuraci\u00f3n desactiva precisamente esa posibilidad por defecto. <\/p>\n<p>En realidad, tener muchos diccionarios puede ser \u00fatil si queremos insertar un conjunto de cadenas, pero accidentalmente insertamos \u2018basura\u2019. Digamos que primero insertamos cadenas malas, y luego insertamos buenas. Entonces, el diccionario se dividir\u00e1 en muchos diccionarios peque\u00f1os. Algunos de ellos contendr\u00e1n \u2018basura\u2019, pero los \u00faltimos tendr\u00e1n cadenas buenas. Y si leemos, digamos, solo la \u00faltima porci\u00f3n, funcionar\u00e1 r\u00e1pido. <\/p>\n<p><img decoding=\"async\" alt=\"Optimizaci\u00f3n de cadenas en ClickHouse. Informe de Yandex\" src=\"\/wp-content\/uploads\/2020\/03\/834ba3295ace98870334aa10a78e4781.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nAntes de hablar sobre las ventajas de LowCardinality, debo decir que es poco probable que logremos reducir los datos en el disco (aunque puede suceder), porque ClickHouse comprime los datos. Hay una opci\u00f3n por defecto: LZ4. Tambi\u00e9n se puede hacer la compresi\u00f3n con ZSTD. Pero ambos algoritmos ya implementan la compresi\u00f3n de diccionario, por lo que nuestro diccionario externo en ClickHouse no ser\u00e1 de gran ayuda. <\/p>\n<p>Para no quedarme en palabras, tom\u00e9 algunos datos de la m\u00e9trica \u2014 String, LowCardinality(String) y Enum \u2014 y los guard\u00e9 en diferentes tipos de datos. Resultaron en tres columnas, donde se registraron mil millones de filas. En la primera columna, CodePage, solo hay 62 valores. Y es evidente que en LowCardinality(String) se comprimieron mejor. String un poco peor, pero esto probablemente se debe a que las cadenas son cortas, almacenamos sus longitudes, y ocupan mucho espacio, se comprimen mal. <\/p>\n<p>Si tomamos PhoneModel, hay 48,000 \u2014 ya m\u00e1s, y las diferencias entre String y LowCardinality(String) pr\u00e1cticamente no existen. Para URL tambi\u00e9n solo ahorramos 2 GB \u2014 creo que no vale la pena confiar en eso. <\/p>\n<h3>Evaluaci\u00f3n de la velocidad de trabajo<\/h3>\n<p>\n<img decoding=\"async\" alt=\"Optimizaci\u00f3n de cadenas en ClickHouse. Informe de 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\">Enlace desde la diapositiva<\/a><\/noindex><\/b><\/p>\n<p>Ahora evaluemos la velocidad de trabajo. Para ello, utilic\u00e9 un conjunto de datos que describe los viajes en taxi en Nueva York. Este <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/toddwschneider\/nyc-taxi-data\">est\u00e1 disponible<\/a><\/noindex> est\u00e1 en GitHub. Contiene poco m\u00e1s de mil millones de viajes. Ah\u00ed se reflejan la ubicaci\u00f3n, el tiempo de inicio y fin del viaje, el m\u00e9todo de pago, el n\u00famero de pasajeros e incluso el tipo de taxi \u2014 verde, amarillo y Uber. <\/p>\n<p><img decoding=\"async\" alt=\"Optimizaci\u00f3n de cadenas en ClickHouse. Informe de Yandex\" src=\"\/wp-content\/uploads\/2020\/03\/0901669dec01b0f956d6976e3aa8b741.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nHice la primera consulta bastante simple \u2014 pregunt\u00e9 d\u00f3nde se solicita m\u00e1s frecuentemente un taxi. Para ello, necesitas tomar la ubicaci\u00f3n desde donde se solicit\u00f3, hacer un GROUP BY sobre ella y contar usando la funci\u00f3n count. Aqu\u00ed ClickHouse da alg\u00fan resultado. <\/p>\n<p><img decoding=\"async\" alt=\"Optimizaci\u00f3n de cadenas en ClickHouse. Informe de Yandex\" src=\"\/wp-content\/uploads\/2020\/03\/50983341e20bcbc1b5adbaed35f8624d.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nPara medir la velocidad de procesamiento de la consulta, cre\u00e9 tres tablas con los mismos datos, pero utilic\u00e9 tres tipos de datos diferentes para nuestra ubicaci\u00f3n inicial \u2014 String, LowCardinality y Enum. LowCardinality y Enum resultaron ser cinco veces m\u00e1s r\u00e1pidos que String. Enum es m\u00e1s r\u00e1pido porque trabaja con n\u00fameros. LowCardinality porque implementa una optimizaci\u00f3n GROUP BY. <\/p>\n<p><img decoding=\"async\" alt=\"Optimizaci\u00f3n de cadenas en ClickHouse. Informe de Yandex\" src=\"\/wp-content\/uploads\/2020\/03\/e2ce4f2127d8728287488c85c92085fc.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nComplicamos a\u00fan m\u00e1s la consulta \u2014 preguntamos d\u00f3nde se encuentra el parque m\u00e1s popular en Nueva York. Nuevamente, lo mediremos por d\u00f3nde se piden m\u00e1s taxis, pero filtraremos solo aquellas ubicaciones que contienen la palabra \"parque\". Tambi\u00e9n a\u00f1adiremos la funci\u00f3n like. <\/p>\n<p><img decoding=\"async\" alt=\"Optimizaci\u00f3n de cadenas en ClickHouse. Informe de Yandex\" src=\"\/wp-content\/uploads\/2020\/03\/7cf6fd64751f3ae578581caddde17aaf.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nObservamos el tiempo \u2014 vemos que Enum de repente comenz\u00f3 a ralentizarse. Adem\u00e1s, funciona a\u00fan m\u00e1s lento que el tipo de dato est\u00e1ndar String. Esto ocurre porque la funci\u00f3n like no est\u00e1 optimizada para Enum. Nos vemos obligados a convertir nuestras cadenas de Enum a cadenas normales \u2014 estamos haciendo m\u00e1s trabajo. LowCardinality(String) tampoco est\u00e1 optimizado por defecto, pero all\u00ed like funciona sobre el diccionario, por lo tanto, la consulta se acelera en comparaci\u00f3n con String. <\/p>\n<p>Al trabajar con Enum, existe un problema m\u00e1s global. Si queremos optimizarlo, debemos hacerlo en cada parte del c\u00f3digo. Supongamos que hemos escrito una nueva funci\u00f3n; es necesario pensar en la optimizaci\u00f3n para Enum. En cambio, en LowCardinality, todo est\u00e1 optimizado por defecto.<\/p>\n<p><img decoding=\"async\" alt=\"Optimizaci\u00f3n de cadenas en ClickHouse. Informe de Yandex\" src=\"\/wp-content\/uploads\/2020\/03\/459243eb5b3dd993393d0184b224ea09.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nVeamos la \u00faltima consulta, que es m\u00e1s artificial. Simplemente calcularemos la funci\u00f3n hash de nuestra ubicaci\u00f3n. La funci\u00f3n hash es una consulta bastante lenta y se tarda en procesarse, por lo que todo se retrasar\u00e1 en un factor de tres.<\/p>\n<p><img decoding=\"async\" alt=\"Optimizaci\u00f3n de cadenas en ClickHouse. Informe de Yandex\" src=\"\/wp-content\/uploads\/2020\/03\/a5f49c22748971646ec358eb52d3feda.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nLowCardinality sigue funcionando m\u00e1s r\u00e1pido, aunque aqu\u00ed no hay filtrado. Esto se debe a que nuestras funciones trabajan \u00fanicamente sobre el diccionario. La funci\u00f3n de c\u00e1lculo de hash tiene un argumento; puede procesar menos datos y tambi\u00e9n puede devolver LowCardinality. <\/p>\n<p><img decoding=\"async\" alt=\"Optimizaci\u00f3n de cadenas en ClickHouse. Informe de Yandex\" src=\"\/wp-content\/uploads\/2020\/03\/7842b7eb2debb4a4b1d4cbc3488deb32.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nNuestro plan global es alcanzar una velocidad de operaci\u00f3n no inferior a la de String en todos los casos y mantener las optimizaciones. Y tal vez alg\u00fan d\u00eda reemplacemos String por LowCardinality, actualizar\u00e1s ClickHouse y todo funcionar\u00e1 un poco m\u00e1s r\u00e1pido.<br \/>\n<br \/>Fuente: <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.2 - 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\/es\/blog\/administrirovanie\/optimizacziya-strok-v-clickhouse-doklad-yandeksa\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.2\" \/>\n\t\t<meta property=\"og:locale\" content=\"es_ES\" \/>\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\/es\/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\udd47Optimizaci\u00f3n de cadenas en ClickHouse. Presentaci\u00f3n de Yandex | ProHoster","description":"La base de datos anal\u00edtica ClickHouse procesa una gran variedad de cadenas, consumiendo recursos. Para acelerar el rendimiento del sistema, se a\u00f1aden constantemente nuevas optimizaciones.","canonical_url":"https:\/\/prohoster.info\/es\/blog\/administrirovanie\/optimizacziya-strok-v-clickhouse-doklad-yandeksa","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"es_ES","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\/es\/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\/es\/wp-json\/wp\/v2\/posts\/74737","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/comments?post=74737"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/posts\/74737\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/media\/74738"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/media?parent=74737"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/categories?post=74737"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/tags?post=74737"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}