sql >> Databasteknik >  >> RDS >> Mysql

Allvarliga problem med MySQL-frågans prestanda efter att ha lagt till villkor

Ange SHOW CREATE TABLE .

Jag hoppas få se dessa sammansatta index:

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

Tyvärr, eftersom code är LONGTEXT , detta är inte möjligt för entity :INDEX(type, code, entityId) . Detta kommer därför inte att vara särskilt effektivt:

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

Jag ser LIMIT med en ORDER BY -- bryr du dig om vilket värde du får?

Det skulle nog vara bättre skrivet som

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

(Är du säker på blandningen av e3 och v9 ?)

Inslagning...

Detta tvingar fram LEFT JOIN för att bli JOIN . Och den tar bort den då inre ORDER BY .

Då bestämmer förmodligen Optimizern att det är bäst att börja med 68e9145e-43eb-4581-9727-4212be41bef5 , som jag kallar val AS v11 :

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

Om detta är en EAV-tabell, då är allt den gör att verifiera att [, 1514] har värdet 'bar2'. Detta verkar inte vara ett vettigt test.

utöver min tidigare rekommendation.

Jag skulle föredra EXPLAIN SELECT ... .

EAV

Förutsatt val är ett traditionellt EAV-bord, skulle detta förmodligen vara mycket bättre:

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

De två ID:n har ingen praktisk användning (såvida jag inte missar något). Om du tvingas använda dem på grund av ett ramverk är det olyckligt. Marknadsföring (entityId, attributeId) till PK gör att value hämtas lite snabbare.

Det finns inget användbart sätt att inkludera en LONGTEXT i vilket index som helst, så några av mina tidigare förslag behöver ändras.




  1. Oväntad Clustered Index Fragmentation

  2. Använder DATE_ADD med ett kolumnnamn som intervallvärde

  3. mysql välj summagrupp efter datum

  4. Subtraktion mellan två sql-frågor