我正在查询具有以下架构的数据库:
People
------
PersonId
PeopleTags
----------
PeopleId
TagId
Tags
----
TagId
Guid
一个人可能有多个标签,并且在查询时要求是找到具有所有一组强制性标签和任何一组可选标签的人。
目前,我正在为每个强制性标签做一个单独的子查询,并为可选标签做一个子查询,这给了我这样的东西:
SELECT People.*
FROM People
WHERE
PeopleId IN (SELECT PeopleId FROM PeopleTags WHERE TagId IN (SELECT TagId FROM Tags WHERE Guid = '83c55f3d...')
AND PeopleId IN (SELECT PeopleId FROM PeopleTags WHERE TagId IN (SELECT TagId FROM Tags WHERE Guid = '8159248a...')
AND PeopleId IN (SELECT PeopleId FROM PeopleTags WHERE TagId IN (SELECT TagId FROM Tags WHERE Guid IN ('737d9015...', 'b7a5974e...')
可以有任意数量的强制和可选标签,我们偶尔会收到此错误:
查询处理器用尽了内部资源,无法生成查询计划。这是一个罕见的事件,仅适用于极其复杂的查询或引用大量表或分区的查询。请简化查询。如果您认为您错误地收到了此消息,请联系客户支持服务以获取更多信息。
研究此错误表明这是由于具有大型 IN 列表的子查询(这完全可能与代码一样)。
有没有更好的方法来编写这个查询?我曾多次尝试加入表格,但如果我这样做,它不会返回任何结果。
SELECT People.*
FROM People
INNER JOIN PeopleTags ON PeopleTags.PersonId = People.PersonId
INNER JOIN Tags t1 on t1.TagId = PeopleTags.TagId and t1.Guid = '8159248A...'
INNER JOIN Tags t2 on t2.TagId = PeopleTags.TagId and t2.Guid = '415DF7A3...'
我可以改变
PeopleId IN (SELECT PeopleId FROM PeopleTags WHERE TagId IN (SELECT TagId FROM Tags WHERE Guid = '83c55f3d...')
至
PeopleId IN (SELECT PeopleId FROM PeopleTags INNER JOIN Tags ON Tags.TagId = PeopleTags.TagId WHERE Guid = '83c55f3d...')
对于每个强制性标签,这会有所不同吗?