sql >> Base de Datos >  >> RDS >> Mysql

¿Cómo acelerar el conteo seleccionado (*) con grupo por y dónde?

Aquí hay varias cosas que probaría, en orden de dificultad creciente:

(más fácil) - Asegúrese de tener el índice de cobertura correcto

CREATE INDEX ix_temp ON relations (relation_title, object_title);

Esto debería maximizar el rendimiento dado su esquema existente, ya que (¡a menos que su versión del optimizador de mySQL sea realmente tonta!) Minimizará la cantidad de E/S necesarias para satisfacer su consulta (a diferencia de si el índice está en el orden inverso donde el índice completo debe escanearse) y cubrirá la consulta para que no tenga que tocar el índice agrupado.

(un poco más difícil) - asegúrese de que sus campos varchar sean lo más pequeños posible

Uno de los desafíos de rendimiento con los índices varchar en MySQL es que, al procesar una consulta, el tamaño completo declarado del campo se extraerá a la RAM. Entonces, si tiene un varchar (256) pero solo usa 4 caracteres, aún está pagando el uso de RAM de 256 bytes mientras se procesa la consulta. ¡Ay! Entonces, si puede reducir sus límites de varchar fácilmente, esto debería acelerar sus consultas.

(más difícil) - Normalizar

El 30% de sus filas que tienen un solo valor de cadena es un grito claro para normalizar en otra tabla para que no esté duplicando cadenas millones de veces. Considere normalizar en tres tablas y usar ID enteros para unirlas.

En algunos casos, puede normalizar debajo de las cubiertas y ocultar la normalización con vistas que coincidan con el nombre de la tabla actual... entonces solo necesita hacer que sus consultas INSERTAR/ACTUALIZAR/ELIMINAR sean conscientes de la normalización, pero puede dejar sus SELECCIONES en paz .

(más difícil) - Hash sus columnas de cadena e indexe los hashes

Si normalizar significa cambiar demasiado código, pero puede cambiar su esquema un poco, puede considerar crear hashes de 128 bits para sus columnas de cadena (usando Función MD5 ). En este caso (a diferencia de la normalización) no tiene que cambiar todas sus consultas, solo los INSERT y algunos de los SELECT. De todos modos, querrá codificar sus campos de cadena y luego crear un índice en los hash, p.

CREATE INDEX ix_temp ON relations (relation_title_hash, object_title_hash);

Tenga en cuenta que deberá jugar con SELECT para asegurarse de que está haciendo el cálculo a través del índice hash y no extrayendo el índice agrupado (requerido para resolver el valor de texto real de object_title para satisfacer la consulta).

Además, si el título_relación tiene un tamaño de varchar pequeño pero el título del objeto tiene un tamaño largo, entonces puede aplicar hash solo a título_objeto y crear el índice en (relation_title, object_title_hash) .

Tenga en cuenta que esta solución solo ayuda si uno o ambos campos son muy largos en relación con el tamaño de los hash.

También tenga en cuenta que hay impactos interesantes en la distinción entre mayúsculas y minúsculas/intercalación debido al hash, ya que el hash de una cadena en minúsculas no es lo mismo que el hash de una cadena en mayúsculas. Por lo tanto, deberá asegurarse de aplicar la canonicalización a las cadenas antes de codificarlas; en otras palabras, solo use hash en minúsculas si se encuentra en una base de datos que no distingue entre mayúsculas y minúsculas. También es posible que desee recortar los espacios desde el principio o el final, dependiendo de cómo su base de datos maneje los espacios iniciales/posteriores.