SHOW CREATE TABLE
を入力してください 。
これらの複合インデックスを見たいと思います:
`val`: (entityId, attributeId) -- order is not critical
残念ながら、code
LONGTEXT
です 、これはentity
では不可能です :INDEX(type, code, entityId)
。したがって、これはあまり効率的ではありません:
SELECT entityId
from entity
where code = v9.Value
and type = 97
limit 1
LIMIT
が表示されます ORDER BY
を使用 -どの値を取得するか気になりますか?
おそらくそれは次のように書くほうがよいでしょう
WHERE EXISTS ( SELECT 1 FROM entity
WHERE entityID = e3.entityID
AND code = v9.Value
AND type = 97 )
(e3
の混合についてはよろしいですか およびv9
?)
ラッピング...
これにより、LEFT JOIN
が強制されます JOIN
になる 。そしてそれはその時内側のORDER BY
を取り除きます 。
次に、オプティマイザーはおそらく68e9145e-43eb-4581-9727-4212be41bef5
から始めるのが最善であると判断します。 、私はこれをval AS v11
と呼んでいます :
JOIN val AS v11 ON (v11.entityId = e2.id
and v11.attributeId = 1614)
AND v11.Value = 'bar2')
これがEAVテーブルの場合、[、1514]の値が「bar2」であることを確認するだけです。これは賢明なテストのようには思えません。
以前の推奨事項に加えて。
EXPLAIN SELECT ...
がいいです 。
EAV
val
を想定 は従来のEAVテーブルですが、これはおそらくはるかに優れています:
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
2つのIDは実用的ではありません(何かが足りない場合を除く)。フレームワークのためにそれらを使用することを余儀なくされた場合、それは残念です。 (entityId、attributeId)をPKにプロモートすると、value
がフェッチされます。 少し速くなります。
LONGTEXT
を含める便利な方法はありません どのインデックスでも、以前の提案のいくつかを変更する必要があります。