Mysql
 sql >> Database >  >> RDS >> Mysql

Seri problemi di prestazioni delle query MySQL dopo l'aggiunta di condizioni

Si prega di fornire SHOW CREATE TABLE .

Spero di vedere questi indici compositi:

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

Ahimè, perché code è LONGTEXT , questo non è possibile per entity :INDEX(type, code, entityId) . Quindi questo non sarà molto efficiente:

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

Vedo LIMIT con un ORDER BY -- ti interessa quale valore ottieni?

Probabilmente sarebbe meglio scriverlo come

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

(Sei sicuro della combinazione di e3 e v9 ?)

Avvolgimento...

Questo forza il LEFT JOIN per diventare JOIN . E si sbarazza dell'allora interno ORDER BY .

Quindi l'Ottimizzatore probabilmente decide che è meglio iniziare con 68e9145e-43eb-4581-9727-4212be41bef5 , che chiamo val AS v11 :

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

Se questa è una tabella EAV, tutto ciò che fa è verificare che [, 1514] abbia valore 'bar2'. Questo non sembra un test sensato.

oltre alla mia precedente raccomandazione.

Preferirei EXPLAIN SELECT ... .

AV

Assumendo val è un tavolo EAV tradizionale, questo sarebbe probabilmente molto meglio:

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

I due ID non hanno alcuna utilità pratica (a meno che non manchi qualcosa). Se sei costretto a usarli a causa di un framework, è un peccato. La promozione (entityId, attributeId) come PK rende il recupero del value un po' più veloce.

Non esiste un modo utile per includere un LONGTEXT in qualsiasi indice, quindi alcuni dei miei suggerimenti precedenti devono essere modificati.