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.