我有一个问题。以下查询需要花费2到3秒才能完成,我不知道为什么。我有2个表涉及一个项目列表,另一个表格包含每个项目的属性列表。 items表使用唯一主键索引,属性表具有外键约束。
项目表之间的关系是属性的一对多。
我不确定如何加快查询速度,并感谢任何建议。
数据库是MYSQL inodb
EXPLAIN SELECT * FROM eshop_items AS ite WHERE (SELECT attValue FROM eshop_items_attributes WHERE attItemId=ite.ItemId ANd attType=5 AND attValue='20')='20' ORDER BY itemAdded DESC LIMIT 0, 18;
id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra
1 PRIMARY ite ALL NULL NULL NULL NULL 57179 Using where; Using filesort
2 DEPENDENT SUBQUERY eshop_items_attributes ref attItemId attItemId 9 gabriel_new.ite.itemId 5 Using where
索引:eshop_items_attributes
Name Fieldnames Index Type Index method
attItemId attItemId Normal BTREE
attType attType Normal BTREE
attValue attValue Normal BTREE
索引:eshop_items
Name Fieldnames Index Type Index method
itemCode itemCode Unique BTREE
itemCodeOrig itemCodeOrig Unique BTREE
itemConfig itemConfig Normal BTREE
itemStatus itemStatus Normal BTREE
无法使用连接,因为item_attributes表是一个键 - >价值对表。因此,对于items_attributes表中的每条记录,可以有许多项目ID
这是一个示例
item_id attribute_index attribute_value
12345 10 true
12345 2 somevalue
12345 6 some other value
32456 10 true
32456 11 another value
32456 2 somevalue
因此,连接不起作用,因为我无法将items_attributes表中的多行连接到items表中的一行。
我无法写一个查询,其中attribute_index = = 2 AN attribute_index = 10.我总是得不到任何结果。
:(
答案 0 :(得分:1)
将查询从关联更改为IN,看看会发生什么。
SELECT *
FROM eshop_items AS ite
WHERE ItemId IN (
SELECT attItemId
FROM eshop_items_attributes
WHERE attType=5
AND attValue='20')
ORDER BY itemAdded DESC
LIMIT 0, 18
您可以通过在eshop_items_attributes上将btree更改为位图来获得更多收益。但要注意:位图会对INSERT / UPDATE产生影响。
答案 1 :(得分:0)
“依赖子信息”是此查询中的杀戮性能。它必须为外部查询中的每个不同的ItemId运行子查询一次。作为一个连接应该好多了:
SELECT ite.* FROM eshop_items AS ite
INNER JOIN eshop_items_attributes AS a ON ite.ItemId = a.attItemId
WHERE a.attType = 5 AND a.attValue = 20
ORDER BY ite.itemAdded DESC LIMIT 0, 18;
答案 2 :(得分:0)
我发现将此类查询视为join
:
SELECT ite.*
FROM eshop_items ite join
eshop_items_attributes ia
on ia.attItemId = ite.ItemId and
ia.attType = 5 and
ia.attValue='20'
ORDER BY ite.itemAdded DESC
LIMIT 0, 18;
如果每个项目最多只有一个匹配属性,则此方法有效。否则,您需要select distinct
(这可能会影响性能,除非您已经进行了排序)。
为方便join
,请创建索引eshop_items_attributes(attType, attValue, attItemId)
。索引应满足join
而必须读取表,其余的则处理结果集。
相同的索引可能有助于相关子查询。