【问题标题】:SQL Server Query Join taking very long when adding an additional column in the join在联接中添加附加列时,SQL Server 查询联接需要很长时间
【发布时间】:2020-09-10 13:06:57
【问题描述】:

我正在对每个表中具有唯一 ID 的表运行基本查询,这是每个表中的非聚集索引。一个表有 800 万行,另一个有 800,000 行。

当我运行以下命令时,它会在不到一秒的时间内返回 24,000 行:

select     
    a.[ID]      
    ,b.[ID]    
from     
    dbo.tbl_1 a    
join     
    dbo.tbl_2 b    
on 
    a.unique_id = b.unique_id 

但是,当我在连接中添加一个额外的列时,这将显着减少记录集,这大约需要 8 分钟

select     
    a.[ID]      
    ,b.[ID]    
from     
    dbo.tbl_1 a    
join     
    dbo.tbl_2 b    
on 
    a.unique_id = b.unique_id 
    AND a.code_letter = b.code_letter

“code_letter”列只有一个字母,设置为 varchar(1)。我正在挠头,试图理解为什么这是挂起的。问题是我已经运行了一个包含 20,000 个连接排列的动态 sql 插入查询,而且花费的时间太长了。

编辑 在尝试了这么多方法之后,我意识到一个简单的select * 似乎工作非常有效,而选择特定的列是罪魁祸首。这是我select *时的执行计划:

这是我选择特定列时的执行计划:

同样,我的连接完全相同,但列选择不同。

【问题讨论】:

  • 您是否尝试在 code_letter 列上创建索引?
  • 我有,但由于某种原因没有帮助.....但即使有,这将是一个烦人的情况,我必须为每次迭代创建一个索引并删除这也可能很耗时。
  • 我想知道它是否与执行计划的缓存或类似的事情有关。它似乎是由动态 SQL 引发的,该动态 SQL 会在连接中使用不同的列反复运行插入查询?
  • 关于性能问题,请出示来自EXPLAIN的查询计划。 8 分钟是单个查询本身还是您的 动态 sql 插入查询 过程的结果?如果是后者,则显示更完整的 TSQL 代码。
  • 它来自单个查询。这是在 t-sql 中,所以我不能使用解释。我提出了动态部分,以防有理由相信这会导致意外问题。

标签: sql performance sql-server-2012 execution-time database-tuning


【解决方案1】:

OP 说,他没有得到预期的结果,根据他的观察,我会提供不同的解决方案。

我要做的是,执行以下操作并将数据获取到临时表

select     
    a.[ID] as aID      
    ,b.[ID] as bID
    ,a.code_letter as aCode_letter  
    ,b.code_letter as bCode_letter
into #t
from     
    dbo.tbl_1 a    
join     
    dbo.tbl_2 b    
on 
    a.unique_id = b.unique_id 

然后执行下面的

Select aID, bID from #t Where aCode_letter = bCode_letter

select DISTINCT a.*    
into #ta
from     
    dbo.tbl_1 a    
join     
    dbo.tbl_2 b    
on 
    a.unique_id = b.unique_id 

select DISTINCT b.*    
into #tb
from     
    dbo.tbl_1 a    
join     
    dbo.tbl_2 b    
on 
    a.unique_id = b.unique_id 

然后执行

Select a.ID, b.ID 
from #ta a
Inner Join #tb b 
on a.unique_id = b.unique_id and a.Code_letter = b.Code_letter

【讨论】:

  • 我试过了,不幸的是它很耗时。这是我学到的最新信息:当我运行时:Select * 似乎会在几秒钟内返回结果,而当我选择特定列时,它会旋转几分钟。我以前从未见过这种情况,这是相当出乎意料的行为。
  • 那你为什么不那样做。 IE。选择 * 然后分别做第二部分?或者单独获取 a.* 并将 b.* 放入另一个临时 tbl,然后加入那些 2
  • 问题是我不得不对列进行大量重命名。如果这有助于确定为什么执行计划如此不同,我将在原始问题中添加执行计划差异。
  • 请尝试我的新建议
  • 这确实有效,尽管它似乎是一种应该可以避免的解决方法。谢谢!
猜你喜欢
  • 2016-02-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-07-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多