Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Performance 此SQL游标的改进-It';太慢了!_Performance_Sql Server 2008_Cursor - Fatal编程技术网

Performance 此SQL游标的改进-It';太慢了!

Performance 此SQL游标的改进-It';太慢了!,performance,sql-server-2008,cursor,Performance,Sql Server 2008,Cursor,我有一个使用游标的sql过程,但它非常慢。我希望通过使用基于集合的操作或诸如此类的方法来提高速度,但我不知道如何将其应用于此特定过程: declare @isMulti bit declare @QuestionID int declare db_cursor cursor FAST_FORWARD for select distinct QuestionID from tblQuestions (nolock) where

我有一个使用游标的sql过程,但它非常慢。我希望通过使用基于集合的操作或诸如此类的方法来提高速度,但我不知道如何将其应用于此特定过程:

    declare @isMulti bit
    declare @QuestionID int
    declare db_cursor cursor FAST_FORWARD for
        select distinct QuestionID
        from tblQuestions (nolock)
        where ID=@ID

    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 QuestionID=@QuestionID and ID=@ID)
               end
               else if(@isMulti=0)
               begin
                    update tblAnswers
                    set col1 = AnswerID, col2 = 1, col3 = (select LEN(count(*)) from tblAnswers where QuestionID=@QuestionID and ID=@ID)
               end

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

谢谢你的帮助

我可能遗漏了一些东西,但是如果从where子句中去掉@QuestionId,为什么这一位在游标之外不起作用呢

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

在不了解更多元数据的情况下,我不确定如何处理问题的多元素,但这应该是一个很好的答案:

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

您可以跨连接更新答案表,即连接ID上问题的答案,然后使用where子句限制@ID。

Ted,我认为缓慢的原因可能是,除了您使用光标之外,每次都通过光标更新完整的TBLANSWER。我希望答案表中有多行,因为在设计过程中使用了光标。在决定从光标更改为基于集合的OP之前,您是否考虑向WHERE表中添加WHERE子句?< /P> 关于我的答案

如果udf很昂贵,那么我会在问题表中添加一列,或者在无法修改问题表的情况下创建一个新表。在插入或更新问题时,使用触发器,使用函数结果的“多”标志填充新列。
使用以下代码作为模型更新sp中的答案表。使用问题ID和“multi”标志的值调用SP


你想用这个程序做什么?也许一个更新查询就足够了。我正在检查一个问题是否是多个问题,然后根据这些信息更新这些问题的答案。问题表不包含指定其是否为多个的列,我必须调用光标中当前问题id的函数进行检查。多个或不多个更新之间的差异是什么?如图所示,如果问题为多个,则将范围内答案的col1、col2和col3设置为特定值。col1=1或answerid,col2=1,col3=count()或len(count())您从未填充过
@isMulti
对不起,我应该更清楚-对于每个问题ID,我必须检查该问题是否是多个问题,因此,在检查问题是否回答之前,光标将循环检查每个要检查的问题。@Ted Mosbey-我在不了解您的数据的情况下进行了这项工作,但它应该为您提供一个很好的指针Hanks,尽管-基于多值(在UDF中计算),col3有所不同。如果mulit col3=select count(),否则col3=select len(count()),则无法根据问题表中的某些计算更新答案表中的值。如果@mulit=1,则回答.col3=x,否则回答.col3=y。它不是基于questionID,而是需要questionID来计算该问题的isMulti。^谢谢。我花了几个小时才意识到这一点。我的程序快了很多(1:13秒)-以
update tblAnswers
set col2 =1,
col1 = CASE @isMulti THEN 1 Else AnswerID
col3 = CASE @isMulti THEN (select count(*) from tblAnswers where ID=@ID) ELSE (select LEN(count(*)) from tblAnswers where ID=@ID)
from tblQuestions
inner join tblAnswers on tblQuestions.QuestionID= tblAnswers.QuestionID
WHERE tblQuestions.QuestionID= @ID