2013-06-04 23 views
2

我在包含750 000个条目的表上运行查询时出现性能问题。它需要15到20秒才能执行,在那段时间阻止访问数据库并创建大量错误日志(当然还有愤怒的客户)。需要帮助来提高某些TSQL“不存在”查询性能

下面是该查询:

DECLARE @FROM_ID AS UNIQUEIDENTIFIER = 'XXX' 
DECLARE @TO_ID AS UNIQUEIDENTIFIER = 'YYY' 

update tbl_share 
set user_id = @TO_ID 
where user_id = @FROM_ID 
and not exists (
    select * 
    from tbl_share ts 
    where ts.file_id = file_id 
    and ts.user_id = @TO_ID 
    and ts.corr_id = corr_id 
    and ts.local_group_id = local_group_id 
    and ts.global_group_id = global_group_id 
) 

我那种坚持,现在因为我的TSQL知识是有限的。 我想知道如果:

  • 我应该创建一个临时表
  • 我应该选择别的东西比“*”

我没有很多机会来运行测试,因为它的一个生产数据库,并且在白天有永久的10-20个客户连接。

感谢您的帮助!

+1

这似乎是无用的:'和ts.corr_id = corr_id 和ts.local_group_id = local_group_id 和ts.global_group_id = global_group_id' –

+0

@RBarryYoung哦,THX,我会修改我的神话 –

+0

另一种方法通过使用通用表达式(CTE)来提高性能。 @Tim Schmelter:是的。 – sjkm

回答

0

重构你的代码逻辑怎么样?

DECLARE @FROM_ID AS UNIQUEIDENTIFIER = 'XXX' 
DECLARE @TO_ID AS UNIQUEIDENTIFIER = 'YYY' 

IF NOT EXISTS (select * 
    from tbl_share ts 
    where ts.user_id = @TO_ID) 
BEGIN 

    update tbl_share 
    set user_id = @TO_ID 
    where user_id = @FROM_ID 

END 

因此,您事先做了检查,并且只在需要的情况下更新数据库。

HTH

+0

感谢您的方法,但我不能因为我必须保持约束 ** ts.corr_id = corr_id 和ts.local_group_id = local_group_id 和ts.global_group_id = global_group_id ** –

+0

好吧,我认为那么你错过了一些指数,例如一个包含在NOT EXISTS语句中的所有列。 CREATE NONCLUSTERED INDEX [IX_TBL_SHARE_EXISTS] ON [TBL_SHARE](的file_id,USER_ID,corr_id,local_group_id,global_group_id)WITH(PAD_INDEX = OFF,STATISTICS_NORECOMPUTE = OFF,SORT_IN_TEMPDB = OFF,IGNORE_DUP_KEY = OFF,DROP_EXISTING = OFF,ONLINE = OFF,ALLOW_ROW_LOCKS = ON,ALLOW_PAGE_LOCKS = ON)ON [主要] –

0

让我们从优化select开始。
检查查询计划。
如果这是PK,那么它是分散的?

select * 
from tbl_share 
where user_id = @FROM_ID 
and not exists (
    select * 
    from tbl_share ts 
    where ts.file_id = file_id 
    and ts.user_id = @TO_ID 
    and ts.corr_id = corr_id 
    and ts.local_group_id = local_group_id 
    and ts.global_group_id = global_group_id 
    ) 

select tUpdate.* 
from tbl_share as tUpdate 
left outer join tbl_share as tExists 
    on tUpdate.user_id = @FROM_ID 
and tExists.user_id = @TO_ID 
and tExists.file_id = tUpdate.file_id 
and tExists.corr_id = tUpdate.corr_id 
and tExists.local_group_id = tUpdate.local_group_id 
and tExists.global_group_id = tUpdate.global_group_id 
where tExists.user_id is null