[英]MySQL select with multiple many to many joins causing very slow query
Using the following table structure: 使用以下表结构:
A user can choose to filter items by a number of fields in the items
table itself, and can also choose any number of properties
that the item must have. 用户可以选择按
items
表本身中的多个字段过滤项目,也可以选择项目必须具有的任意数量的properties
。 The search needs to choose an item with all properties, not just one of them. 搜索需要选择具有所有属性的项,而不仅仅是其中一项。 I'm currently using the format
我目前正在使用格式
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
I have also tried, as a way of specifying search purely by WHERE rather than by JOIN 我还尝试过一种纯粹通过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...
However this approach seemed, if anything, to take even longer to query the set. 但是,这种方法(如果有的话)似乎需要更长的时间来查询集合。 With about 4 properties chosen query time is about 4-5s, much more and the queries tend to get killed or bring the MySQL server down altogether.
选择大约4个属性时,查询时间约为4-5s,而且查询往往会被杀死或使MySQL服务器完全瘫痪。
As far as I am aware all the _id fields are indexed on each table, being the primary keys of their respective tables too. 据我所知,所有_id字段都在每个表上建立了索引,它们也是它们各自表的主键。
Are there ways to improve the query or might I need to limit the number of options that can be queried? 有什么方法可以改善查询,还是可能需要限制可以查询的选项数量?
Use post aggregation filtering if you want all property_id 如果需要所有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 is the number of property_id IN(3,4,5,6) 4是property_id IN(3,4,5,6)的数量
我认为您只需要在item_properties
上item_properties
索引:
create index idx_item_properties_2 on item_properties(item_id, property_id)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.