我有一張表格每晚都被插入,然後作爲報表查詢。SQL Server - 存儲過程性能問題
爲查詢工作的存儲過程具有動態SQL字符串,分頁和其中的兩個臨時表。
它非常適用第一週
從第二週開始,它的性能開始急劇下降(花費3.5分鐘時的恢復)
我已經獲得並運行動態的輸出字符串SQL,它顯着更快(2秒),所以我猜它可能與編譯器相關
然後我做了一些優化,如將count(*)
更改爲count(event_id)
,表現立即回來,但第二天早上表現再次下降。
然後我改變select into
明確聲明臨時表,表現馬上回來,但第二天早上表現再次下降。
然後我改變聲明臨時表明確回select into
,表現立即回來,但第二天早上表現再次下降。
所以我想它無關代碼優化,似乎每一次SP得到了編譯時間,性能只能爲不到24小時
我想到夜間插入,這是更好也24小時循環,然後我發現這個with (nolock)
的事情,這可能已經鎖定了表1
加入Nolock
後,該存儲過程運行良好了一個星期,在這之後我們再次得到了同樣的問題,不同的是這一次,只有調用SP的網頁很慢,從DB運行的SP很快...
這裏是動態SQL存儲過程:
CREATE PROCEDURE [dbo].[fs_1_usp_query]
@paramerter_client_id int = null,
@paramerter_event_type_id int = null,
@paramerter_start_date datetime = null,
@paramerter_end_date datetime = null,
@paramerter_page_index int = 1,
@paramerter_sort_direction varchar(20),
@paramerter_page_count int = 30
AS
BEGIN
SET ARITHABORT ON;
SET NOCOUNT ON;
declare @sql nvarchar(max)
set @sql = '
create table #output2
(
page_index int,
rownumber int,
page_count int,
client_id int,
date datetime,
)
--insert into #output1
select
page_count = count(event_id) over(),
table1.*
into #output1'
set @sql = @sql + '
from
table1 table1 with (nolock)
inner join
table2 table2 with (nolock)
on
............................
inner join
table3 table3 with (nolock)
on
............................
inner join
table4 table4
on
............................
where
............................
if (@paramerter_client_id is not null)
set @sql = @sql + ' and table2.client_id = @paramerter_client_id'
if (@paramerter_event_type_id is not null)
set @sql = @sql + ' and table2.event_type_id = @paramerter_event_type_id'
if (@paramerter_start_date is not null)
set @sql = @sql + ' and table2.created_date >= @paramerter_start_date'
if (@paramerter_end_date is not null)
set @sql = @sql + ' and table2.created_date <= @paramerter_end_date'
declare @lv_begin_index int
declare @lv_end_index int
set @lv_begin_index = ((@paramerter_page_index - 1) * @paramerter_page_count) + 1
set @lv_end_index = @lv_begin_index + @paramerter_page_count
set @sql = @sql + '
UPDATE #output1
SET osat_rating = ''-''
WHERE LEFT(osat_rating , 1) = ''-''
insert into #output2
select
page_index = ' + convert(varchar, @paramerter_page_index) + ',
row_number() over (order by [' + @paramerter_sort_expression + '] '+ @paramerter_sort_direction + ') as rownumber,
#output1.*
from #output1
select #output2.*
from #output2
where
rownumber >= ' + convert(varchar, @lv_begin_index) + '
and
rownumber < ' + convert(varchar, @lv_end_index) '
set @sql = @sql + '
drop table #output1
drop table #output2 '*
下面是靜態SQL的快照試圖按照你的建議:
Where
Column3 = Coalesce(@parameter3, Column3)
and
(@start_date is null or Column_created_date >= @start_date)
and
(@param_1 is null
or
(@param_1 not in (‘ConstantString1’, 'ConstantString2') and Column1 = @param_1)
or
(@param_1 = ‘ConstantString1’ and Column1 like 'ConstantString1%')
or
(@param_1 = ‘ConstantString2’ and (Column1 is null or Column1 = ''))
)
If(@parameter_sort_direction = 'DESC')
Begin
insert into #temp_table_result
select
page_index = convert(varchar, @parameter_page_index),
row_number() over
(
order by CASE
WHEN @parameter_sort_expression = 'Column1' THEN Column1
WHEN @parameter_sort_expression = 'Column2' THEN Column2
WHEN @parameter_sort_expression = 'Column3' THEN Column3
WHEN @parameter_sort_expression = 'Column4' THEN Column4
WHEN @parameter_sort_expression = 'Column5' THEN Column5
WHEN @parameter_sort_expression = 'Column6' THEN Column6
WHEN @parameter_sort_expression = 'Column7' THEN Column7
WHEN @parameter_sort_expression = 'Column8' THEN Column8
END desc--CASE
-- WHEN @parameter_sort_direction = 'ASC' THEN asc
-- WHEN @parameter_sort_expression = 'DESC' THEN desc
--END
) as rownumber,
#temp_table_staging.*
from #temp_table_staging
END
你能爲我們定義「快」和「慢」嗎?我有需要幾天運行的特效,還有一些會考慮0.5s很慢。 – JNK 2012-01-30 13:08:45
並且在生產代碼中遠離Nolock - 它會導致您錯過已經提交的行。 – 2012-01-30 13:37:09
感謝您的問題。使用相同的數據集時,正常工作需要2秒鐘,如果不正常,需要約3.5分鐘。 – Ree5un 2012-01-30 14:54:02