我有一个功能,我想要更高效。我知道大部分费用都是寻求索引。我想知道是否有办法将这两个索引求解合并为一个。
这是我的功能
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
答案 0 :(得分: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表,然后将内存表中的结果读入两个变量
答案 1 :(得分:0)
包括
CHARINDEX(@Query,data)
光标中的,而不是在循环内首先计算它。这应该削减大约一半的寻求。虽然搜索是SQL Server最有效的访问方式,但消除其中一半仍然可以帮助任何查询。
您还可以尝试在游标中包含数据并使用该值计算@StringResult。如果这将有助于非常依赖于数据列的平均大小。如果它足够小,应该显着加快速度。什么“足够小”取决于很多事情,你应该尝试一下。如果数据是VARCHAR(1000)在光标中拉动它很可能会有所帮助,但是如果它是VARCHAR(MAX)并且平均长度为2 MB则很可能会受到伤害。
最后,正如Pete所说,最好的解决方案是以基于集合的方式编写它,但这可能更复杂,因为您无法从单个select语句中调用存储过程。