MySQL选择多个多对多的连接,导致查询速度非常慢

时间:2014-11-18 12:22:59

标签: mysql join many-to-many mysql-slow-query-log

使用以下表格结构:

项目(约20,000条记录)

  • ITEM_ID

属性(~30条记录)

  • PROPERTY_ID

Item_properties(~40,000条记录)

  • ID
  • PROPERTY_ID
  • ITEM_ID

用户可以选择按items表本身中的多个字段过滤项目,也可以选择项目必须具有的任意数量的properties。搜索需要选择具有所有属性的项目,而不仅仅是其中一项。我目前正在使用格式

SELECT item.field...
FROM items
INNER JOIN item_properties AS ip1 ON ip1.item_id=item.item_id and ip1.property_id=3
INNER JOIN item_properties AS ip2 ON ip2.item_id=item.item_id and ip2.property_id=4
INNER JOIN item_properties AS ip3 ON ip3.item_id=item.item_id and ip3.property_id=5
INNER JOIN item_properties AS ip4 ON ip4.item_id=item.item_id and ip4.property_id=6
etc...
WHERE item.something_else='words'
GROUP BY item_id

我也尝试过,仅仅通过WHERE而不是JOIN来指定搜索方式

SELECT item.field...
FROM items
WHERE item.something_else='words'
and item_id IN (select item_id from item_properties where property_id=3)
and item_id IN (select item_id from item_properties where property_id=4)
and item_id IN (select item_id from item_properties where property_id=5)
and item_id IN (select item_id from item_properties where property_id=6)
etc...

然而,如果有的话,这种方法似乎需要更长的时间来查询集合。有大约4个属性选择查询时间大约是4-5秒,更多,查询往往会被杀死或完全关闭MySQL服务器。

据我所知,所有_id字段都在每个表上编入索引,也是各自表的主键。

是否有改进查询的方法,或者我是否需要限制可查询的选项数量?

2 个答案:

答案 0 :(得分:1)

如果您想要所有property_id

,请使用后置聚合过滤
SELECT item.field
FROM items
INNER JOIN item_properties AS ip1 ON ip1.item_id=item.item_id and  
and ip1.property_id IN(3,4,5,6)
WHERE item.something_else='words'
GROUP BY item.field
HAVING COUNT(DISTINCT property_id )=4

4是property_id IN(3,4,5,6)

的数量

答案 1 :(得分:0)

我认为您只需要item_properties上的索引:

create index idx_item_properties_2 on item_properties(item_id, property_id)