【问题标题】:exists() condition performance issueexists() 条件性能问题
【发布时间】:2013-05-09 08:22:34
【问题描述】:

我有一个无限期运行的简单 SQL 查询(见下文)(我无法等待它完成)

if exists(
    select 1 
    from [files].[Contacts_Migration_Template] c 
    where not exists(select 1 
                     from [files].[Additional_Contact_Migration_Template] 
                     where contact = c.[migration id])
) print 'warning message'

但是子查询(if exists(subquery) print 'warning message')本身会立即执行(见下面的截图)

“完整”查询

子查询

为两个查询生成的估计执行计划(见下文)表明子查询必须比“完整”查询具有更高的查询成本......其中,正如我上面所说,第一个(子查询)立即运行,第二个(“ full") 运行无限长...

发生了什么事?


原始查询

【问题讨论】:

  • 快速的使用散列连接并且只扫描Additional_Contact_Migration_Template一次。慢速扫描它(或至少一个假脱机副本)多次。统计数据是最新的吗?
  • 但是如果速度更快,为什么第一个的相对查询成本是 83%(相对于 17%)?
  • 这是基于错误的估计。它可能假设嵌套循环内侧的执行次数将比现实中实际发生的次数少得多。实际上可能是row goals gone rogue 的情况。
  • 它仍然太简单的查询要走这么久 :) 进一步模式子查询工作得很快,外部存在()只需要打印/抛出
  • 如果您添加缺少的索引,那么它应该可以解决问题。或者您可以使用查询提示来强制使用哈希连接而不是嵌套循环。

标签: sql-server-2012 exists query-performance


【解决方案1】:

试试这个:

if exists(

    select 1 from [files].[Contacts_Migration_Template] c left join 
    [files].[Additional_Contact_Migration_Template] a
    on c.[migration id]=a.contact 
    where a.contact is null
       )

print 'warning message'

【讨论】:

  • 在帖子中查看我的更正(我添加了原始查询) - 最初我有加入,但它们也工作了很长时间
  • 由于我办公室的一些检查站,我看不到您的图片。那么您是否在查询中使用了左连接?
  • 是的。最初,我使用了与您写的完全相同的查询:)
  • 您在表格的匹配列中是否有正确的索引(c.[migration id]=a.contact)?
  • 不,我没有,但我不想让它们只用于这个问题解决方案:) 我所有的 [files].TableName 表都是即时生成的,我不想添加这个中间表的索引 - 这是矫枉过正
【解决方案2】:

我使用临时表来中断执行顺序。它有帮助。

select 1 [x] into #tmp_87624435
from [files].[Contacts_Migration_Template] c
where not exists( select 1
    from [files].[Additional_Contact_Migration_Template]
    where contact = c.[migration id]);
if exists(select 1 from #tmp_87624435) throw 51000, 'warning', 1;

但我仍然认为对于这样一个简单的问题来说,即使这样也有点过分了:)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-06-11
    • 1970-01-01
    • 2012-11-21
    • 2014-01-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多