繁体   English   中英

左外部联接SQL Server中的性能问题

[英]Performance Issue in Left outer join Sql server

在我的项目中,我需要在同一张表中找到基于旧修订和新修订的差异任务。

id     |    task   |   latest_Rev
1             A            N
1             B            N
2             C            Y
2             A            Y
2             B            Y

预期结果:

   id       |     task   | latest_Rev   
   2               C           Y

所以我尝试了以下查询

  Select new.* 
  from Rev_tmp nw with (nolock)
  left outer 
  join rev_tmp  old with (nolock)
  on   nw.id -1  = old.id
  and  nw.task = old.task
  and  nw.latest_rev = 'y'
  where old.task is null

当我的表有超过20k条记录时,此查询需要更多时间? 如何减少时间?

在我公司不允许使用子查询

使用LAG功能删除自连接

SELECT *
FROM   (SELECT *,
               CASE WHEN latest_Rev = 'y' THEN Lag(latest_Rev) OVER(partition BY task ORDER BY id) ELSE NULL END AS prev_rev
        FROM   Rev_tmp) a
WHERE  prev_rev IS NULL 
  1. Latest_Rev应该是位类型(等效于布尔值),我的性能更好( 在此处详细说明)
  2. 可能是您可以在id,task,Latest_Rev列上添加索引吗

您可以尝试此查询(用不存在的方式替换左外)

Select * 
from Rev_tmp nw
where nw.latest_rev = 'y' and not exists
(
select * from rev_tmp  old
where nw.id -1  = old.id and  nw.task = old.task
)

我的答案假设

  • 您不能更改索引
  • 您不能使用子查询
  • 所有字段均单独索引

如果查看查询,则真正减少结果集的唯一值是latest_rev='Y' 如果要消除这种情况,您肯定会进行表格扫描。 因此,我们希望使用索引来评估该条件。 不幸的是,仅重视“ Y”和“ N”的字段可能会被忽略,因为它将具有可怕的选择性。 如果您仍然诱使SQL Server使用它,则可能会获得更好的性能。 如果latest_rev上的索引称为idx_latest_rev尝试以下操作:

Set transaction isolated level read uncommitted

Select new.* 
from Rev_tmp nw with (index(idx_latest_rev))
left outer 
join rev_tmp  old 
on   nw.id -1  = old.id
and  nw.task = old.task
where old.task is null
and  nw.latest_rev = 'y'

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM