gpt4 book ai didi

MySQL 优化过滤键值对作为记录

转载 作者:可可西里 更新时间:2023-11-01 08:07:47 28 4
gpt4 key购买 nike

我有一个数据库结构,旨在以易于扩展的方式存储特定对象的属性。
有一个“对象”表。

+----+----------------------
| id | ....(name, type, etc)
+----+----------------------

接下来,我有一个“属性”表。

+----+------+
| id | Name |
+----+------+

最后,一个“关系”表,用于将所有数据保存为具有相应值的属性对象对(作为主键)。

+--------+---------+-------+
| id_obj | id_attr | value |
+--------+---------+-------+

我需要一次获取满足多个条件的对象的 ID。例如,我有名为“Type”和“City”的属性,我需要为这些属性的对应值为“Apartment”和“City b”的对象获取 ID。

从昨天开始我的头撞到墙上后,我设法想出了最好的解决方案(好吧,这个查询的唯一好处是它确实有效并获取了所需的记录):

SELECT objects.id
FROM (attributes INNER JOIN relations ON attributes.id = relations.id_attr)
INNER JOIN objects ON relations.id_obj = objects.id
WHERE objects.id
IN (
SELECT objects.id
FROM (attributes INNER JOIN relations ON attributes.id = relations.id_attr)
INNER JOIN objects ON relations.id_obj = objects.id
WHERE attributes.name = 'Type' AND relations.value = 'Apartment'
)
AND objects.id
IN (
SELECT objects.id
FROM (attributes INNER JOIN relations ON attributes.id = relations.id_attr)
INNER JOIN objects ON relations.id_obj = objects.id
WHERE attributes.name = 'City' AND relations.value = 'City b'
)
GROUP BY objects.id ASC
LIMIT 0 , 20

问题是,存储的数据量可能会变得有些大,而且我担心所有这些子查询(可能需要指定一些 10-15 个过滤器),每个子查询都解析整个数据库,可能会导致严重的性能问题(并不是说即使我的 SQL 技能有限,我也很确定一定有更好的方法来完成我需要做的事情)。
另一方面,对数据库进行剧烈更改并不是真正的选择,因为使用它的代码在很大程度上取决于当前的数据库结构。
有没有办法在单个查询中以我需要的方式检查属性,对存储的数据结构进行有限的更改或不进行更改?


工作查询,相当于上面的查询,但优化得更好,归功于 DRapp :

SELECT STRAIGHT_JOIN
rel.id_obj
from
relations rel
join attributes atr
on rel.id_attr = atr.id
where
( rel.value = 'Apartment' AND atr.name = 'Type' )
or ( rel.value = 'City b' AND atr.name = 'City' )
group by
rel.id_obj
having
count(*) = 2
limit
0, 20

最佳答案

这应该可以满足您的需求...每个“OR”d where 子句条件,您都可以继续添加为合格项。然后,只需调整“有”子句以满足与您允许的标准相同的数量......我将关系表放在第一位,因为它会在城市的“值”或类型值上有一个较小的匹配集...确保您在“值”列的关系表上有一个索引。

SELECT STRAIGHT_JOIN
rel.id_obj
from
relations rel
join attributes atr
on rel.id_addr = atr.id
where
( rel.value = 'Apartment' AND atr.name = 'Type' )
or ( rel.value = 'Some City' AND atr.name = 'City' )
group by
atr.id_obj
having
count(*) = 2
limit
0, 20

如果你想要这个结果中的所有实际对象数据,你可以将它包装成类似...

select obj.*
from
( complete SQL statement above ) PreQuery
join Object obj on PreQuery.id_obj = obj.id

关于MySQL 优化过滤键值对作为记录,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6890135/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com