sql >> Database >  >> RDS >> Mysql

Ernstige prestatieproblemen met MySQL-query's na het toevoegen van een voorwaarde

Geef a.u.b. SHOW CREATE TABLE .

Ik hoop deze samengestelde indexen te zien:

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

Helaas, want code is LONGTEXT , dit is niet mogelijk voor entity :INDEX(type, code, entityId) . Dit zal dus niet erg efficiënt zijn:

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

Ik zie LIMIT met een ORDER BY -- maakt het je uit welke waarde je krijgt?

Waarschijnlijk zou dat beter geschreven kunnen worden als

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

(Weet je zeker van de mix van e3 en v9 ?)

Inpakken...

Dit dwingt de LEFT JOIN om JOIN te worden . En het verwijdert de dan innerlijke ORDER BY .

Dan besluit de Optimizer waarschijnlijk dat het het beste is om te beginnen met 68e9145e-43eb-4581-9727-4212be41bef5 , die ik val AS v11 . noem :

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

Als dit een EAV-tabel is, is alles wat het doet verifiëren dat [, 1514] de waarde 'bar2' heeft. Dit lijkt geen verstandige test.

naast mijn eerdere aanbeveling.

Ik zou liever EXPLAIN SELECT ... .

EAV

Uitgaande van val is een traditionele EAV-tafel, dit zou waarschijnlijk veel beter zijn:

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 twee ID's hebben geen praktisch nut (tenzij ik iets mis). Als je vanwege een framework genoodzaakt bent om ze te gebruiken, is dat jammer. Promotie (entityId, attributeId) om de PK te zijn, maakt het ophalen van value een beetje sneller.

Er is geen handige manier om een ​​LONGTEXT . op te nemen in elke index, dus sommige van mijn eerdere suggesties moeten worden gewijzigd.




  1. Hoe json-array filteren op elke geretourneerde rij?

  2. Hoe krijg ik kolomnamen in Laravel 4?

  3. Tel opeenvolgende numerieke waarden in SQL

  4. SQL-sleutelwoord gebruiken in titel van tabel of kolom