【问题标题】:SQL Server 2008 query plan warns "No Join Predicate", query takes very long timeSQL Server 2008 查询计划警告“No Join Predicate”,查询需要很长时间
【发布时间】:2014-02-08 01:09:06
【问题描述】:

这是我的 SQL

select DISTINCT d.* from Device d, Company c1 
WHERE 

EXISTS ( select * from (SELECT * FROM [dbo].[Split] ('HENNEPIN COUNTY MN', ',')) as s     
        WHERE c1.CompanyName like '%' + s.items + '%' AND d.CustomerID  c1.CompanyID)
OR  
EXISTS ( select * from (SELECT * FROM [dbo].[Split] ('HENNEPIN COUNTY MN', ',')) as s     
        WHERE d.CustomerName like '%' + s.items + '%')

在排序上,它将 OR 误解为笛卡尔积,您可以在此处阅读:http://www.scarydba.com/2009/09/15/no-join-predicate/

有什么办法可以避免这种情况?

【问题讨论】:

  • 你能展示样本数据和想要的结果吗?设备和公司如何相关?也许您应该使用 UNION / UNION ALL 而不是在我看来像 CROSS JOIN 的东西?
  • 公司和设备不相关吗?可以from device d join company c1 on d.companyid = c1.companyid 吗?
  • 正如汤姆所说,问题在于设备和公司没有与谓词连接。 OR 不是问题。
  • 感谢菲尔的有用见解。

标签: sql sql-server-2008 join


【解决方案1】:

你说的是

select DISTINCT d.* from Device d, Company c1 

但您不会以任何方式加入DeviceCompany。结果,您将获得来自Device 的每条记录与来自Company 的每条记录配对,并获得Device 中的记录数乘以Company 中返回的记录数。

由于您只返回来自Device 的字段,难怪您需要DISTINCT,难怪需要这么长时间。

如果那是您真正想要的,您可以使用 CROSS JOIN 操作删除该消息:

select d.*
from   Device d
   CROSS JOIN Company c1

有关 CROSS JOIN 操作的更多信息,请参阅here

但我们或许可以加快速度。试试这个:

 ;
 WITH s AS (
    SELECT *
    FROM   [dbo].[Split] ('HENNEPIN COUNTY MN', ',') s
 )  
 SELECT  d.*
 FROM    Device d
 WHERE   EXISTS ( 
            select * 
            from   s
                JOIN Companies c1
                   ON c1.CompanyName like '%' + s.items + '%' 
           where d.CustomerID = c1.CompanyID
        )
    OR  EXISTS (
           select  *
           from    S
           where   d.CustomerName like '%' + s.items + '%'
        )

这可能会进一步改进,但鉴于我不确定此查询试图解决什么问题,这是我目前能做的最好的事情。

【讨论】:

    猜你喜欢
    • 2016-02-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-09
    • 2015-05-17
    相关资源
    最近更新 更多