2014-03-30 19 views
0

低性能的代碼,我有一些嵌套程序,這表明低性能。爲了找到瓶頸,我在t-sql代碼中插入了一些調試標記,用於衡量性能低下的代碼塊性能。這調試標誌是這樣的:如何找到我的T-SQL程序

select @start_point = GETDATE() -- start measuring point 
--- 
open @session_license_fee_cur -- suspected chunk of code 
--- 
select @end_point = GETDATE()-- end measuring point 
select @duration = datediff(ms, @start_point, @end_point) 
select @log_info_total = 'Opening cursor license_fee (bills_supp_create_license_fee) (@class_id = ' + cast(@class_id as nvarchar) + ')'; 

exec bills_supp_save_calculation_log @duration, @log_info_total, @house_id, @account_id, @log_level -- procedure for creating log (simple insert into log table pes_bl_bills_calculation_log_total) 

pes_bl_bills_calculation_log_total表運行我運行查詢的程序,看看性能最低的代碼之後。它看起來像這樣

set @session_license_fee_cur = cursor static for 
    select activity_id 
      , addendum_id 
      , service_id 
      , active_from 
      , active_to 
    from dbo.bills_supp_get_activate_license_fee_for_sessions_by_house(@active_from, @active_to, @house_id) 

select @start_point = GETDATE() 
--- 
open @session_license_fee_cur 
--- 
select @end_point = GETDATE() 
select @duration = datediff(ms, @start_point, @end_point) 
select @log_info_total = 'Opening cursor license_fee (bills_supp_create_license_fee) (@class_id = ' + cast(@class_id as nvarchar) + ')'; 
exec bills_supp_save_calculation_log @duration, @log_info_total, @house_id, @account_id, @log_level 

換句話說打開@session_license_fee_cur作品非常緩慢(約501980毫秒)。

我想在SQL Server Management Studio中運行給定參數的這段代碼,以查看查詢計劃並嘗試優化它。我這樣運行它

declare @active_from date = '01.03.2014' 
declare @active_to date = '01.04.2014' 
declare @house_id integer = 11927 
     select activity_id 
       , addendum_id 
       , service_id 
       , active_from 
       , active_to 
     from dbo.bills_supp_get_activate_license_fee_for_sessions_by_house(@active_from, @active_to, @house_id) 

但它的工作速度非常快(在約0(零)秒內返回3000條記錄)。 什麼在程序

open @session_license_fee_cur 

打開遊標和SQL Server Management Studio中運行它有什麼區別?

declare @active_from date = '01.03.2014' 
declare @active_to date = '01.04.2014' 
declare @house_id integer = 11927 
     select activity_id 
       , addendum_id 
       , service_id 
       , active_from 
       , active_to 
     from dbo.bills_supp_get_activate_license_fee_for_sessions_by_house(@active_from, @active_to, @house_id) 

我的瓶頸在哪裏?

+0

五大昂貴查詢的主要差異是發動機生病後才需要處理光標。您可以嘗試使用FAST_FORWARD提示該遊標,但通常最好的方法是避免使用遊標。 btw使用sysdatetime()代替getdate() – jean

+0

謝謝Jean。看來我發現了發現的問題。函數bills_supp_get_activate_license_fee_for_sessions_by_house中的子查詢有一個完整掃描查詢會導致降級。 但有一件事我沒有得到。爲什麼在SQL Management Studio中沒有光標的查詢的工作時間約爲零秒,但在查詢中它的工作時間超過5分鐘。 爲什麼這樣的區別? –

+0

您必須查看生成的查詢計劃,這可以爲您提供一些線索(包括關於全表掃描)。也許遊標正在分配大量的內存/ tempdb。嘗試監視CPU,內存和IO,看看遊標聲明做錯了什麼。 – jean

回答

1
+0

謝謝。但前5個查詢並不顯示我通過日誌顯示的內容。它向我顯示了從我的日誌角度來看足夠快的程序。 也許我錯了,但的「讀膨脹」查詢前兩個顯示我在列「總的物理讀」號3811不幸的是,我不知道是不是太多或沒有,但我的直覺告訴我,這是沒有這麼多。我對嗎? –