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

Problemas graves de rendimiento de consultas de MySQL después de agregar una condición

Proporcione SHOW CREATE TABLE .

Espero ver estos índices compuestos:

`val`: (entityId, attributeId)   -- order is not critical

Por desgracia, porque code es LONGTEXT , esto no es posible para entity :INDEX(type, code, entityId) . Por lo tanto, esto no será muy eficiente:

        SELECT  entityId
            from  entity
            where  code = v9.Value
              and  type = 97
            limit  1

Veo LIMIT con un ORDER BY -- ¿te importa qué valor obtienes?

Probablemente sería mejor escribirlo como

    WHERE EXISTS ( SELECT 1 FROM entity
                WHERE entityID = e3.entityID
                  AND code     = v9.Value
                  AND type = 97 )

(¿Estás seguro de la mezcla de e3 y v9 ?)

Envolviendo...

Esto fuerza el LEFT JOIN para convertirse en JOIN . Y se deshace del entonces interno ORDER BY .

Luego, el Optimizer probablemente decida que es mejor comenzar con 68e9145e-43eb-4581-9727-4212be41bef5 , al que llamo val AS v11 :

JOIN val AS v11 ON (v11.entityId = e2.id
             and  v11.attributeId = 1614)
             AND  v11.Value = 'bar2')

Si se trata de una tabla EAV, todo lo que hace es verificar que [, 1514] tiene el valor 'bar2'. Esto no parece una prueba sensata.

además de mi recomendación anterior.

Preferiría EXPLAIN SELECT ... .

EAV

Asumiendo val es una tabla EAV tradicional, probablemente sería mucho mejor:

CREATE TABLE `val` (
  `attributeId` int(11) NOT NULL,
  `entityId` int(11) NOT NULL,
  `Value` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci
  PRIMARY KEY(`entityId`,`attributeId`),
  KEY `IX_val_attributeId` (`attributeId`),
) ENGINE=InnoDB AUTO_INCREMENT=2325375 DEFAULT CHARSET=latin1

Las dos identificaciones no tienen ningún uso práctico (a menos que me falte algo). Si se ve obligado a usarlos debido a un marco, es desafortunado. Promocionar (entityId, atributoId) para que sea el PK hace que se obtenga value un poco más rápido.

No existe una forma útil de incluir un LONGTEXT en cualquier índice, por lo que es necesario cambiar algunas de mis sugerencias anteriores.