clickhouse estructura del índice y la optimización de consultas

clickhouse hay muchos motores, todos de los siguientes contenidos basado en el motor MergeTree

Primer vistazo a la red Xiaguan clave principal de contenido relacionado:

Los ejemplos de la utilidad del índice - con el fin de MergeTree por ejemplo,
motor de la serie MergeTree, los datos son parte de un archivos multigrupo, en general, todos los meses (Nota del traductor: CK unidad de división más pequeña es el mes) habrá una parte del archivo ( aquí es parte del bloque).
Cada porción de datos está dispuesto lexicográficamente en la clave principal. Por ejemplo, si tiene una clave principal es (ContadorID, Fecha), que será la primera línea de datos de acuerdo con ContadorID tipo, si ContadorID mismo, ordenadas por fecha.
estructuras de datos matriz clave principal, los archivos se parece a una etiqueta, el archivo de la etiqueta es la clave primaria para cada línea index_granularity intervalo (índice de tamaño de partícula).
MergeTree motor, la configuración predeterminada de index_granularity Inglés 8192.
La clave principal es (ContadorID, Fecha) es una vista esquemática de almacenamiento son los siguientes:

En primer lugar, de acuerdo con el tipo ContadorID, si ContadorID mismo, ordenadas por fecha

Una clave principal es los datos del índice ordenado dispersos. Vemos la parte de datos de la figura manera (en principio, debería ser mantenido en la figura duración media de la marca, sino un código ASCI muy conveniente manera).
archivos de etiquetas, simplemente como una regla. clave principal para la eficiencia de las búsquedas por rangos de filtración es muy alta. Para consulta de operaciones, CK lee un conjunto de archivos de etiquetas puede contener los datos de destino.
Por ejemplo, si la consulta es ContadorID EN ( 'a', ' h'), el servidor leerá el archivo marcado como la correspondencia entre [0,3] y [6,8] en el archivo de datos.
Si la consulta es ContadorID EN ( 'a', ' h') y la fecha especificada = 3, el servidor de archivos se leen la bandera correspondiente entre [1,3] y [7,8} archivo de datos.
A veces, el efecto de filtrado de la clave primaria no es muy buena, por ejemplo, sólo la segunda columna aparece en la condición de consulta:
si las condiciones de consulta única fecha = 3, el servidor lee las tensiones [archivo de datos correspondiente a entre 1, 10).
En el ejemplo anterior, el archivo de etiquetas además de 0, el otro 90% de las necesidades de datos que va a escanear, aunque el índice no es un buen efecto de filtrado, sin embargo, es todavía de algunos datos se pueden saltar.
Por otro lado, si cada ContadorID correspondiente a una pluralidad de datos, el índice se omitirán más datos de fecha. (???)
términos integrados, el índice será siempre un escaneo completo de tabla que algunos sean eficientes.
Acerca de las claves primarias, así como los siguientes puntos deben tenerse en cuenta

índice disperso leerá una gran cantidad de datos innecesarios: leer cada parte de la clave primaria, que será más de lectura de datos index_granularity * 2. Esto es normal, no hay necesidad de un índice disperso está diseñado para reducir el valor de index_granularity .ClickHouse, se ha comprometido a un procesamiento eficiente de grandes cantidades de datos, por lo que un poco de lectura adicional y sin comprometer el rendimiento. index_granularity = 8192 para la mayoría de las escenas es una mejor opción.
No es la única clave primaria, la misma llave puede insertarse en la línea de datos principal.
La clave principal, la misma expresión de función puede estar presente. Tales como, (ContadorID, EVENTDATE, intHash32 ( UserID))
el ejemplo descrito anteriormente, mediante el uso de una función hash, el nombre de usuario correspondiente a una polimerización específica ContadorID y EVENTDATE hecho, por cierto, este método de polimerización, una muestra se puede utilizar en esta función a. índice disperso es adecuado para la tabla de datos en masa, y el archivo de índice disperso en la memoria en sí no es un problema

lento ck optimizado dirección sql de
la partición, el principio es utilizado con frecuencia de datos juntos en la misma región (también pueden ser condiciones en las que basan las particiones), si una pluralidad de regiones y luego en el área es demasiado grande,

clave principal (índice, ese tipo) ordenado por selección de campo: es el campo donde hay duda añade un poco de su interior, en algún lugar en un campo determinado en primer lugar, para distinguir entre moderado grado de atención a la esfera de la discriminación es demasiado pequeña no es bueno, ya que el índice disperso cuando el índice de ck, utilizando una muestra de acuerdo con un tamaño fijo como el valor del índice real, no el árbol binario de MySQL, no se recomienda el uso de terreno particularmente alta distinción.
Dos tipos de claves primarias, una primera ORDER BY (industria, l1_name, l2_name , l3_name, job_city, job_area, row_id), no contiene segundo campo row_id, es decir, ORDER BY (industria, l1_name, l2_name , l3_name, job_city, job_area), row_id que es único en el uso de row_id a consulta donde la condición, se encuentra que el segundo será un mejor rendimiento, row_id a punto de ser eliminado de la clave principal, la consulta mejor

ck la optimización de índices
estructura 1 índice está índice disperso no tomar la analogía de un árbol binario de MySQL

Indexación de la manera correcta
para empezar campo no debe ser una distinción entre un campo de alto grado, si es único, entonces el índice es muy pobre y no puede encontrar la discriminación particularmente pobre, debe encontrar medio discriminación, que se refiere a la configuración el valor, si es grande, se puede encontrar un poco menos columnas de discriminación, si es relativamente pequeño, en busca de una columna ligeramente más grande que el índice de discriminación

boss_info mesa de unos 15 millones de datos, la cantidad de datos G 20

CREATE TABLE bi.boss_info (row_id String, Int32 USER_ID, nombre_usuario String, String género, título de cuerdas, cuerdas is_hr, la certificación de cadena, cadena user_status, user_extra_status cadena, terminación de cadena, lure_content cuerdas, cuerdas de correo electrónico, brand_id Int32, company_name String, Int32 com_id , company_full_name cadena, página web cadena, dirección de cuerdas, brand_completion cadena, brand_certify cadena, la industria de cuerdas, escala de cuerda, la etapa de cuerdas, ADD_TIME cadena, com_description cadena, com_date8 cadena, active_time cadena, unactive_days Int32, cadena job_title, l1_name cadena, l2_name cadena, l3_name cadena, cadena de la ciudad, low_salary Int32, Int32 high_salary, cadena de grado, exp_description cadena, work_years cadena, cadena job_address, job_province cadena, cadena job_city, job_area cadena, cadena job_status,job_num Int32, online_props_buy String, all_item_num Int32, all_income String, online_vip_buy String, online_vip_time String, online_super_vip_buy String, online_super_vip_time String, offline_props_distribute String, offline_props_time String, offline_vip_distribute String, offline_vip_time String, pay_now String, data_dt Fecha) ENGINE = MergeTree () PARTITION BY data_dt ORDER BY (industria, l1_name, l2_name, l3_name, job_city, job_area, row_id) AJUSTES index_granularity = 8192data_dt Fecha) ENGINE = MergeTree () DE REPARTO POR data_dt ORDER BY (industria, l1_name, l2_name, l3_name, job_city, job_area, row_id) AJUSTES index_granularity = 8192data_dt Fecha) ENGINE = MergeTree () DE REPARTO POR data_dt ORDER BY (industria, l1_name, l2_name, l3_name, job_city, job_area, row_id) AJUSTES index_granularity = 8192

CREAR TABLA bi.boss_info2 (row_id String, Int32 USER_ID, nombre_usuario String, String género, título de cuerdas, cuerdas is_hr, la certificación de cadena, cadena user_status, user_extra_status cadena, terminación de cadena, lure_content cuerdas, cuerdas de correo electrónico, brand_id Int32, company_name String, Int32 com_id , company_full_name cadena, página web cadena, dirección de cuerdas, brand_completion cadena, brand_certify cadena, la industria de cuerdas, escala de cuerda, la etapa de cuerdas, ADD_TIME cadena, com_description cadena, com_date8 cadena, active_time cadena, unactive_days Int32, cadena job_title, l1_name cadena, l2_name cadena, l3_name cadena, cadena de la ciudad, low_salary Int32, Int32 high_salary, cadena de grado, exp_description cadena, work_years cadena, cadena job_address, job_province cadena, cadena job_city, job_area cadena, cadena job_status,job_num Int32, online_props_buy String, all_item_num Int32, all_income String, online_vip_buy String, online_vip_time String, online_super_vip_buy String, online_super_vip_time String, offline_props_distribute String, offline_props_time String, offline_vip_distribute String, offline_vip_time String, pay_now String, data_dt Fecha) ENGINE = MergeTree () PARTITION BY data_dt ORDER BY (industria, l1_name, l2_name, l3_name, job_city, job_area) AJUSTES index_granularity = 16,384data_dt Fecha) ENGINE = MergeTree () DE REPARTO POR data_dt ORDER BY (industria, l1_name, l2_name, l3_name, job_city, job_area) AJUSTES index_granularity = 16384data_dt Fecha) ENGINE = MergeTree () DE REPARTO POR data_dt ORDER BY (industria, l1_name, l2_name, l3_name, job_city, job_area) AJUSTES index_granularity = 16384

 La construcción de la diferencia table: la diferencia entre boss_info y boss_info2 se ha retirado el índice de row_id

Fenómeno:
SQL1: la Orden por la SELECT row_id de boss_info límite desc row_id 3; ---- el consumo de grandes
primeros resultados son los siguientes: 999997-1
3 filas del conjunto de la transcurrido: 0,342 seg Procesado 14,62 millones 101 - 500 filas, 279,07 MB .. (.. 42,71 millones de filas / S, 815,10 MB / S) 
SQL2: SELECT row_id de Orden boss_info2 por límite desc row_id 3;.
3 filas en el conjunto de la transcurridos :. 0.061 seg Procesado 14,62 millones de filas, 279,07 MB (240.21 millones de filas / S.. ., 4.58 GB / S). 
SQL3: SELECT * DONDE row_id de boss_info = '999998-1'; ---- consumir grande, el tiempo no es estable, el promedio se mide de nuevo 4-6s
1 filas de la transcurrido SET.. .: 20.228 sec millones de filas procesados 13.16, 24.10 GB (650.83 Thousand filas / s, 1,19 GB / S ..) 
sql4: SELECT * DONDE row_id de boss_info2 = '999997-1';
1 filas en conjunto. Transcurrido: 2,195 seg. Procesada 14,62 millones de filas, 279,08 MB (6,66 millones de filas / s., 127,16 Mb / s). 

sql5: seleccione row_id de boss_info orden por el límite asc row_id 3;
结果中第一条是: 1000010-1
3 filas en conjunto. Transcurrido: 0,058 seg. Procesado 14,62 millones de filas, 279,07 MB (251,10 millones de filas / s, 4,79 Gb / s..) 
Sql6: seleccione row_id de orden boss_info2 por límite asc row_id 3;
3 filas en conjunto. Transcurrido: 0,061 seg. Procesado 14,62 millones de filas, 279,07 MB (240.11 millones de filas / s, 4,58 Gb / s..) 
SQL7: SELECT * FROM boss_info donde row_id = '1000010-1';
1 filas en conjunto. Transcurrido: 4,003 seg. Procesados 13,16 millones de filas, 24.10 GB (3,29 millones de filas / s, 6,02 Gb / s..) 
Sql8: SELECT * FROM boss_info2 donde row_id = '1000010-1';
1 filas en conjunto. Transcurrido: 2,711 seg. Procesada 14,62 millones de filas, 279,07 MB (5,39 millones de filas / s., 102.95 Mb / s.) 

sql9: select count (*) de boss_info;
 resultado: 14.622.978 
 . Todo el escaneo completo de tabla SQL anterior se llevan a cabo se digitalizan 15 millones de datos

sql10: SELECT * FROM boss_info donde la industria = '咨询' y row_id = '999997-1';
1 filas en conjunto. Transcurrido: 0,172 seg. Procesado 147.64 mil filas, 24,10 65B (859.30 mil filas / s, 1,54 Gb / s..) 
这句sql没有进行全表扫描,仅仅扫描了15万左右
sql11: SELECT * FROM boss_info donde l1_name = '技术' y row_id = '999997-1';
1 filas en conjunto. Transcurrido: 1,728 seg. Procesado 4,76 millones de filas, 8,46 GB (2,75 millones de filas / s, 4,89 Gb / s..) 
Sql12: SELECT * FROM boss_info donde l3_name = 'C ++' y row_id = '999997-1';
1 filas en conjunto. Transcurrido: 3,073 seg. Procesado 10,06 millones de filas, 18.03 GB (3,27 millones de filas / s., 5,87 Gb / s). 


SELECT Industria, l1_name, l2_name, l3_name, job_city, job_area, row_id de boss_info Ordenar por límite desc row_id 3;.
3 filas en el conjunto de la transcurrido:. .. 0,264 seg Procesado 14,62 millones de filas, 1,91 GB (55,45 millones de filas / S, 7,24 GB. / S). 
SELECT * de boss_info Ordenar por límite desc row_id 3;.
3 filas en el conjunto de la transcurrido:. .... 3.299 seg Procesado 14,62 millones de filas, 25.51 GB (4,43 millones de filas / s, 7,73 GB / S) 
SELECT * FROM boss_info donde row_id = '999988-9';
comienzo con el ck estructura de índice:
índice disperso típico, es decir, los datos se almacenan de acuerdo con el orden de campos ck por secuencialmente almacenada mientras el ajuste basado en su conjunto (es decir, el índice de tamaño de partícula) para el muestreo datos, el contenido es el orden por corresponde de campo con el valor verdadero;

Descripción del problema :( Supongo que la respuesta es, no hay confirmación plena comprensión correcta)
1 ¿Por sql10 índice en vigor, row_id SQL1 índice y SQL3 no están en vigor, o incluso tirar de eficiencia de la consulta lenta
problemas estructurales de índice, es ck índice disperso, sql10 la industria es sólo la primera parte del índice, por lo que el efecto de índice toma directamente la orientación gama, sin embargo SQL1 y SQL3 en row_id es la última parte del índice, el retorno sería para localizar una amplia gama de mesas, por lo que el valor real de una mesa llena escanear.
Tire razones de eficiencia de consultas lentas:
primeras exploraciones de todo el índice para localizar el rango, pero la gama se dirige a toda la tabla, por lo que este paso es enteramente a hacer más
y llevará a cabo un escaneo completo de tabla

2sql3 y sql4 con un escaneo completo de tabla, por qué los datos de exploración SQL3 24 GB, mientras que sql4 solamente 279m, lo que resulta en más lentas SQL3 10 veces
la cantidad de lagunas de datos en los últimos tiempos ---> row_id en el índice debe ser cargado en todos los campos, no en el índice simplemente escanear el campo row_id

row_id se parte del índice debido a la intervalo de tiempo se coloca con toda row_id (escasa y plomo hasta el final de la sección en el índice), por lo que todo el campo se carga en memoria, row_id encontrar los registros que cumplen los criterios? Cuando no hay índice en el primer partido con row_id, solamente row_id leer la columna, y luego simplemente cargar un row_id rango de tamaño de partícula donde todos los contenidos

3sql1 y sql2 en comparación con el índice pero ¿por qué SQL1 5 veces más lento que la velocidad de procesamiento por qué sql2 SQL1 más rápido
se puede referir a una pregunta, vaya primer índice, pero la marcha blanca real
 

Publicado 41 artículos originales · ganado elogios 6 · Vistas a 50000 +

Supongo que te gusta

Origin blog.csdn.net/bujidexinq/article/details/104955581
Recomendado
Clasificación