2010-11-26 19 views
1

我有一個使用遊標的sql程序,但它確實很慢。我期待提高利用基於集的操作或這樣的事情的速度,但我不知道如何將其應用到這個具體程序:這個SQL遊標的改進 - 它真的很慢!

declare @isMulti bit 
    declare @QuestionID int 
    declare db_cursor cursor FAST_FORWARD for 
     select distinct QuestionID 
     from tblQuestions (nolock) 
     where [email protected] 

    open db_cursor 
    fetch next from db_cursor into @QuestionID 

    while @@FETCH_STATUS = 0 
    begin 
       --check if @isMulti is true or not for the current question 
       if(@isMulti=1) 
       begin 
        update tblAnswers 
        set col1 = 1, col2 = 1, col3 = (select count(*) from tblAnswers where [email protected] and [email protected]) 
       end 
       else if(@isMulti=0) 
       begin 
        update tblAnswers 
        set col1 = AnswerID, col2 = 1, col3 = (select LEN(count(*)) from tblAnswers where [email protected] and [email protected]) 
       end 

       fetch next from db_cursor into @QuestionID 
    end 
close db_cursor 
deallocate db_cursor 

任何幫助的感謝提供!

+0

你在用這個程序試着做什麼?也許一個更新查詢就足夠了。 – vdrmrt 2010-11-26 10:50:40

+0

我在檢查一個問題是否是多個問題,然後根據這些信息更新問題答案。問題表不包含指定它是否爲多的列,我必須調用光標中當前問題標識的函數來檢查。 – Bob 2010-11-26 11:26:47

+0

多重更新之間的差異是多少? – vdrmrt 2010-11-26 11:51:11

回答

1

泰德,我相信慢的原因可能是,除了你正在使用遊標的事實,每次通過遊標更新完整的tblAnswers。我期望答案表中有多行,因爲在設計過程中使用了光標。在決定從遊標更改爲基於集合的操作之前,您會考慮爲答案表的更新添加WHERE子句。

到我answser

如果UDF是昂貴的話,我會一列添加到問題表或創建新表,如果對矯正的問題表是不可能的。使用「multi」標誌填充新列,並使用函數的結果,插入或更新問題時使用觸發器。
使用下面的代碼作爲模型更新sp中的答案表。用問題ID和「多」標誌的值調用SP。

update tblAnswers 
set col2 =1, 
col1 = CASE @isMulti THEN 1 Else AnswerID 
col3 = CASE @isMulti THEN (select count(*) from tblAnswers where [email protected]) ELSE (select LEN(count(*)) from tblAnswers where [email protected]) 
from tblQuestions 
inner join tblAnswers on tblQuestions.QuestionID= tblAnswers.QuestionID 
WHERE tblQuestions.QuestionID= @ID 
1

我可能失去了一些東西,但爲什麼不將光標超出該位工作,如果你在where子句?:

 --check if @isMulti is true or not 
     if(@isMulti=1) 
     begin 
      update tblAnswers 
      set col1 = 1, col2 = 1, col3 = (select count(*) from tblAnswers where [email protected]) 
     end 
     else if(@isMulti=0) 
     begin 
      update tblAnswers 
      set col1 = AnswerID, col2 = 1, col3 = (select LEN(count(*)) from tblAnswers where [email protected]) 
     end 

編輯

取出@QuestionId不知道更多關於元數據我不確定如何處理多元素的問題,但這應該是一個很好的方法來回答:

declare @question table (questionid int, multi int) 
declare @answer table (answerid int, col1 int, col2 int, col3 int) 

insert into @question (questionid, multi) values (1, 0) 
insert into @question (questionid, multi) values (2, 0) 
insert into @question (questionid, multi) values (3, 0) 
insert into @question (questionid, multi) values (4, 1) 
insert into @question (questionid, multi) values (5, 1) 


insert into @answer (answerid, col1, col2, col3) values (1, 0, 0, 0) 
insert into @answer (answerid, col1, col2, col3) values (1, 0, 0, 0) 
insert into @answer (answerid, col1, col2, col3) values (2, 0, 0, 0) 
insert into @answer (answerid, col1, col2, col3) values (2, 0, 0, 0) 
insert into @answer (answerid, col1, col2, col3) values (3, 0, 0, 0) 
insert into @answer (answerid, col1, col2, col3) values (4, 0, 0, 0) 
insert into @answer (answerid, col1, col2, col3) values (4, 0, 0, 0) 
insert into @answer (answerid, col1, col2, col3) values (4, 0, 0, 0) 
insert into @answer (answerid, col1, col2, col3) values (5, 0, 0, 0) 

update @answer 
set col1 = 1, col2 = 1, col3 = (select count(*) from @answer a join @question q on a.answerid = q.questionid where q.multi = 0 and [@answer].answerid = a.answerid) 

select distinct * from @answer 
0

您可以通過連接更新答案表,即參與ID上問題的答案,然後使用where子句限制@ID。