Proszę podać SHOW CREATE TABLE
.
Mam nadzieję, że zobaczę te indeksy złożone:
`val`: (entityId, attributeId) -- order is not critical
Niestety, ponieważ code
to LONGTEXT
, nie jest to możliwe dla entity
:INDEX(type, code, entityId)
. Dlatego nie będzie to bardzo wydajne:
SELECT entityId
from entity
where code = v9.Value
and type = 97
limit 1
Widzę LIMIT
z ORDER BY
-- czy obchodzi Cię, jaką wartość otrzymujesz?
Prawdopodobnie lepiej byłoby napisać to jako
WHERE EXISTS ( SELECT 1 FROM entity
WHERE entityID = e3.entityID
AND code = v9.Value
AND type = 97 )
(Czy jesteś pewien kombinacji e3
i v9
?)
Zawijanie...
Wymusza to LEFT JOIN
zostać JOIN
. I pozbywa się wtedy wewnętrznego ORDER BY
.
Wtedy Optymalizator prawdopodobnie zdecyduje, że najlepiej zacząć od 68e9145e-43eb-4581-9727-4212be41bef5
, który nazywam val AS v11
:
JOIN val AS v11 ON (v11.entityId = e2.id
and v11.attributeId = 1614)
AND v11.Value = 'bar2')
Jeśli jest to tablica EAV, to wszystko, co robi, to sprawdzenie, czy [, 1514] ma wartość 'bar2'. Nie wydaje się to rozsądnym testem.
oprócz mojej poprzedniej rekomendacji.
Wolałbym EXPLAIN SELECT ...
.
EAV
Zakładając val
to tradycyjna tabela EAV, prawdopodobnie byłaby znacznie lepsza:
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
Te dwa identyfikatory nie mają praktycznego zastosowania (chyba że czegoś mi brakuje). Jeśli jesteś zmuszony do ich używania ze względu na ramy, to jest to niefortunne. Promowanie (entityId, attributeId) jako PK powoduje pobranie value
trochę szybciej.
Nie ma użytecznego sposobu na dołączenie LONGTEXT
w dowolnym indeksie, więc niektóre z moich poprzednich sugestii wymagają zmiany.