0

我有一个功能,我想提高效率。我知道大部分成本都在寻找索引上。我想知道是否有办法将这两个索引搜索合并为一个。

这是我的功能

ALTER FUNCTION [dbo].[Search]
(
    @Query nvarchar(150)        
)
RETURNS @result TABLE 
(
    ID int,
    ResultPhrase nvarchar(max),
    Domain nvarchar(50)
)
AS

BEGIN

declare  @id int,
         @OffsetArticle nvarchar(50),
         @OffsetProfile nvarchar(50),
         @index int,
         @domain nvarchar(50),
         @StringResult nvarchar(max),
         @substrIndex int,
         @substrCount int,
         @field nvarchar(40),
         @begin int,
         @end int

        DECLARE pidCursor CURSOR FAST_FORWARD
        FOR select id,OffsetArticle,OffsetProfile from PerfTest where contains (data,@Query)

        open pidCursor
        FETCH NEXT FROM pidCursor INTO @id,@OffsetArticle,@OffsetProfile

        while (@@FETCH_STATUS = 0)
        begin

        select @index = CHARINDEX(@Query,data) from PerfTest where ID=@id

        exec @domain =  dbo.FindDomain @id=@id ,@index=@index, @offsetArticle=@OffsetArticle, @offsetProfile=@OffsetProfile


        if(@domain = N'Profile')
            set @end = SUBSTRING(@offsetProfile,CHARINDEX(N'-',@offsetProfile)+1,len(@offsetProfile)-CHARINDEX(N'-',@offsetProfile))
            set @begin = SUBSTRING(@offsetProfile,1,CHARINDEX(N'-',@offsetProfile)-1)

        if(@domain = N'Article')
            set @end = SUBSTRING(@OffsetArticle,CHARINDEX(N'-',@OffsetArticle)+1,len(@OffsetArticle)-CHARINDEX(N'-',@OffsetArticle))
            set @begin = SUBSTRING(@OffsetArticle,1,CHARINDEX(N'-',@OffsetArticle)-1)



        if(@index - 20 < CAST(@begin as int))
            set @substrIndex = @index
        else
            set @substrIndex = @index - 20

        if(@index + 150 > CAST(@end as int))
            set @substrCount = @end
        else
            set @substrCount = @index + 150 


        select @StringResult = SUBSTRING(data,@substrIndex,@substrCount) from PerfTest where ID=@id

        insert @result (id,ResultPhrase,Domain) values (@id,@StringResult,@domain)


        if(@@FETCH_STATUS = 0)
            FETCH NEXT FROM pidCursor INTO @id,@OffsetArticle,@OffsetProfile

        end
        CLOSE pidCursor
        DEALlOCATE pidCursor

RETURN      
END
4

2 回答 2

0

包括

  CHARINDEX(@Query,data)

在光标中,而不是在循环内首先计算它。这应该会减少大约一半的搜索量。虽然搜索是 SQL Server 最有效的访问方式,但消除其中一半仍然有助于任何查询。

您还可以尝试在游标中包含数据并使用该值计算 @StringResult。如果这会有所帮助,很大程度上取决于数据列的平均大小。如果它足够小,应该可以显着加快速度。“足够小”取决于很多事情,您应该尝试一下。如果数据是 VARCHAR(1000) 将其拉到游标中,它很可能会有所帮助,但是如果它是 VARCHAR(MAX) 且平均长度为 2 MB,则很可能会受到伤害。

最后,正如 Pete 所提到的,最好的解决方案是以基于集合的方式编写它,但这可能更复杂,因为您不能从单个 select 语句中调用存储过程。

于 2012-10-20T19:36:02.887 回答
0

要组合 @index 和 @string 结果查询,您可以执行以下操作:

DECLARE @results TABLE
(index INT, stringresult NVARCHAR(MAX))

INSERT INTO @results(Index,stringresult)
SELECT CHARINDEX(@Query,data) 
      ,SUBSTRING(data,@substrIndex,@substrCount
FROM PerfTest where ID=@id

SET @index = (SELECT index from @results)
SET @stringresults = (SELECT stringresult FROM @results)

这将只读取一次 perftest 表,然后将内存表中的结果读取到两个变量中

于 2012-10-20T13:08:54.390 回答