我有一个类似于Entity
表的模式,与 具有一对多关系Attribute
,与 具有一对多关系Value
。Attribute
有一列Name
,并且Value
有一列Value
:
Entity
------
Id
Name
Attribute
---------
Id
EntityId
Name
Value
-----
Id
AttributeId
Value
我需要能够构建一个查询,该查询将仅返回Entity
具有特定属性/值子项组合的行。目前我正在编写类似这样的查询:
select
*
from Entity e
where exists(
select * from Attribute a
join Value v on v.AttributeId = a.id
where a.EntityId = e.id and a.Name = 'color' and v.Value = 'red')
and exists(
select * from Attribute a
join Value v on v.AttributeId = a.id
where a.EntityId = e.id and a.Name = 'size' and v.Value = 'small')
这可行,但每个额外的属性过滤器都会添加另一个exists
子句,我对性能感到紧张。有没有一种更有效的方法来编写这种类型的查询,或者如果我使用正确的索引等,它是否可能具有完美的性能?
你需要这样的东西:
很难预测您的原始查询是否会出现性能问题。我们不知道您的表有多大、您有哪些索引、您可能添加了多少过滤器、查询需要多快完成,等等。您可能需要考虑以最自然的方式编写查询并衡量性能。如果性能可以接受,请按原样保留代码。
如果确实需要提升性能,可以考虑类似下面的重写:
无论您向子句中添加了多少过滤器,这都会让您对表
attribute
进行一次扫描。一个缺点是您可能会从过滤器中得到一个糟糕的基数估计,但如果过滤器的目标是从表中过滤掉大部分行,那么这可能不是问题。value
HAVING
HAVING
Entity