Angiv venligst SHOW CREATE TABLE
.
Jeg håber at se disse sammensatte indekser:
`val`: (entityId, attributeId) -- order is not critical
Ak, fordi code
er LONGTEXT
, dette er ikke muligt for entity
:INDEX(type, code, entityId)
. Derfor vil dette ikke være særlig effektivt:
SELECT entityId
from entity
where code = v9.Value
and type = 97
limit 1
Jeg ser LIMIT
med en ORDER BY
-- er du ligeglad med, hvilken værdi du får?
Det ville nok være bedre skrevet som
WHERE EXISTS ( SELECT 1 FROM entity
WHERE entityID = e3.entityID
AND code = v9.Value
AND type = 97 )
(Er du sikker på blandingen af e3
og v9
?)
Indpakning...
Dette fremtvinger LEFT JOIN
for at blive JOIN
. Og den slipper af med den dengang indre ORDER BY
.
Så beslutter Optimizer sandsynligvis, at det er bedst at starte med 68e9145e-43eb-4581-9727-4212be41bef5
, som jeg kalder val AS v11
:
JOIN val AS v11 ON (v11.entityId = e2.id
and v11.attributeId = 1614)
AND v11.Value = 'bar2')
Hvis dette er en EAV-tabel, så er det eneste, den gør, at verificere, at [, 1514] har værdien 'bar2'. Dette virker ikke som en fornuftig test.
ud over min tidligere anbefaling.
Jeg foretrækker EXPLAIN SELECT ...
.
EAV
Forudsat val
er et traditionelt EAV-bord, ville dette nok være meget bedre:
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 to ID'er har ingen praktisk brug (medmindre jeg mangler noget). Hvis du er tvunget til at bruge dem på grund af en ramme, er det uheldigt. Fremme (entityId, attributeId) til at være PK'en henter value
lidt hurtigere.
Der er ingen brugbar måde at inkludere en LONGTEXT
på i ethvert indeks, så nogle af mine tidligere forslag skal ændres.