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.