2013-06-04 19 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