条件连接不起作用

时间:2016-07-05 10:23:38

标签: sql sql-server

我有两个实体:productscategories。产品可以是多个类别,但绝大多数是一类(> 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呢?

1 个答案:

答案 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或子查询中)而不是实际的表中加入一个唯一项目列表?