Bitte geben Sie SHOW CREATE TABLE an .
Ich würde hoffen, diese zusammengesetzten Indizes zu sehen:
`val`: (entityId, attributeId) -- order is not critical
Ach, weil code ist LONGTEXT , ist dies für entity nicht möglich :INDEX(type, code, entityId) . Daher wird dies nicht sehr effizient sein:
SELECT entityId
from entity
where code = v9.Value
and type = 97
limit 1
Ich sehe LIMIT mit einem ORDER BY -- Interessiert es Sie, welchen Wert Sie erhalten?
Wahrscheinlich wäre das besser geschrieben als
WHERE EXISTS ( SELECT 1 FROM entity
WHERE entityID = e3.entityID
AND code = v9.Value
AND type = 97 )
(Bist du dir sicher mit der Mischung aus e3 und v9 ?)
Verpackung...
Dies erzwingt den LEFT JOIN um JOIN zu werden . Und es wird das dann innere ORDER BY los .
Dann entscheidet der Optimierer wahrscheinlich, dass es am besten ist, mit 68e9145e-43eb-4581-9727-4212be41bef5 zu beginnen , die ich val AS v11 nenne :
JOIN val AS v11 ON (v11.entityId = e2.id
and v11.attributeId = 1614)
AND v11.Value = 'bar2')
Wenn dies eine EAV-Tabelle ist, überprüft sie lediglich, ob [, 1514] den Wert „bar2“ hat. Dies scheint kein sinnvoller Test zu sein.
zusätzlich zu meiner früheren Empfehlung.
Ich bevorzuge EXPLAIN SELECT ... .
EAV
Angenommen val eine traditionelle EAV-Tabelle ist, wäre diese wahrscheinlich viel besser:
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
Die beiden IDs haben keinen praktischen Nutzen (es sei denn, mir fehlt etwas). Wenn Sie aufgrund eines Frameworks gezwungen sind, sie zu verwenden, ist das bedauerlich. Das Heraufstufen von (entityId, attributeId) zum PK führt zum Abrufen von value etwas schneller.
Es gibt keine sinnvolle Möglichkeit, einen LONGTEXT einzufügen in jedem Index, daher müssen einige meiner vorherigen Vorschläge geändert werden.