我有两个实体:products
和categories
。产品可以是多个类别,但绝大多数是一类(> 99%)。
我有一个查询应该返回一个类别中的所有产品。我在产品表中有一列表明该产品属于多个类别(CwObject_HasMultipleCwEntities
)。如果是这样,则只需要CwObject_MainCwEntity_Guid
。否则,我需要连接到将产品(CwObjects
)链接到类别(CwEntities
)的表格。
这是我到目前为止的查询:
SELECT o.* FROM dbo.CwObject o WHERE CwObject_CwSiteCluster_Guid = '0f178176-9720-41c7-9528-99fdf30005e8'
AND ((CwObject_HasMultipleCwEntities = 0 AND CwObject_MainCwEntity_Guid = '4E614BA0-50E8-4CA1-9A42-D59DBDB6794D')
OR (CwObject_HasMultipleCwEntities = 1 AND
exists (select 1 from EntityObjectLink e where
e.EntityObjectLink_LinkedCwObject_Guid = o.CwObject_Guid
AND e.EntityObjectLink_LinkedCwEntity_Guid = '4E614BA0-50E8-4CA1-9A42-D59DBDB6794D')
)) ORDER BY CwObject_NAME ASC
我有一个测试数据库,其中没有多个类别的产品,因此CwObject_HasMultipleCwEntities
始终为0
。我会假设EntityObjectLink
根本不会被使用,但查询仍然会显示63K records
。
查询计划在此处:https://1drv.ms/u/s!AlCbN2sexrJ-hNJlfEvK07yamw75yw
为什么会这样?
我怎么能实现这种conditional join
呢?
答案 0 :(得分:1)
问题在于优化器会尝试找出运行查询的最佳方法,并且可能会确定这是为了搜索它不需要的数万条记录。
通常这会表明索引存在问题,但您可能无法更改索引策略,或者您对其他查询执行方式感到非常满意?
您可以尝试将查询拆分,使其更加“明显”,即引入最终丢弃的记录没有意义吗?这可能没有帮助,但是这样的事情:
SELECT
o.*
FROM
dbo.CwObject o
WHERE
CwObject_CwSiteCluster_Guid = '0f178176-9720-41c7-9528-99fdf30005e8'
AND CwObject_HasMultipleCwEntities = 0
AND CwObject_MainCwEntity_Guid = '4E614BA0-50E8-4CA1-9A42-D59DBDB6794D'
UNION ALL
SELECT DISTINCT
o.*
FROM
dbo.CwObject o
INNER JOIN EntityObjectLink e ON e.EntityObjectLink_LinkedCwObject_Guid = o.CwObject_Guid
AND e.EntityObjectLink_LinkedCwEntity_Guid = '4E614BA0-50E8-4CA1-9A42-D59DBDB6794D'
WHERE
CwObject_HasMultipleCwEntities = 1
ORDER BY
CwObject_NAME;
我对你的桌子挂在一起的方式做了一些假设。您可能会发现最好从该UNION的第二部分删除DISTINCT并从您的链接表(在CTE或子查询中)而不是实际的表中加入一个唯一项目列表?