我有一个带有Iterface的Web应用程序,用户可以在其上上传文件。 excel文件的数据被收集,连接并传递给
一个存储过程,用于处理并返回数据。
存储过程的简要说明。
存储过程收集字符串,使用分号将其分解,然后将其存储在临时变量表中。
另一个过程通过临时表运行,在其中进行计数以通过比较每个字符串来找到精确匹配数和近似匹配数
包含一个视图
与第一行中的每一行进行比较的所有名称
精确匹配计数是例如在视图中找到eact字符串的位置。.((Bobby Bolonski)
使用levenshtein距离算法数据库函数以2的频率进行近似匹配。
提示表@ temp1。
结果(名称,精确匹配数和近似匹配数)存储在最终临时表中。
在最后一个临时表上运行一条select语句,以将所有数据返回给应用程序。
我的问题是,当我传递带有27000个名称的大文件(如excel文件)时。 IT花费了大约2个小时来处理和返回数据库中的数据。
我已经检查了服务器和应用程序都在哪里以及数据库都在哪里。
在应用程序服务器上。内存和CPU使用率均低于15%
在数据库服务器上。内存和CPU使用率均低于15%。
我正在寻找有关我可以采取哪些改进措施以加快流程速度的建议。
下面是存储过程的副本,它正在执行所有工作并将结果返回到Web应用程序。
CREATE PROCEDURE [dbo].[FindMatch]
@fullname varchar(max),@frequency int,
@delimeter varchar(max) AS
set @frequency = 2
declare @transID bigint
SELECT @transID = ABS(CAST(CAST(NEWID() AS VARBINARY(5)) AS Bigint))
DECLARE @exactMatch int = 99
DECLARE @approximateMatch int = 99
declare @name varchar(50)
DECLARE @TEMP1 TABLE (fullname varchar(max),approxMatch varchar(max), exactmatch varchar(max))
DECLARE @ID varchar(max)
--declare a temp table
DECLARE @TEMP TABLE (ID int ,fullname varchar(max),approxMatch varchar(max), exactmatch varchar(max))
--split and store the result in the @temp table
insert into @TEMP (ID,fullname) select * from fnSplitTest(@fullname, @delimeter)
--loop trough the @temp table
WHILE EXISTS (SELECT ID FROM @TEMP)
BEGIN
SELECT Top 1 @ID = ID FROM @TEMP
select @name = fullname from @TEMP where id = @ID
--get the exact match count of the first row from the @temp table and so on until the loop ends
select @exactMatch = count(1) from getalldata where replace(name,',','') COLLATE Latin1_general_CI_AI = @name COLLATE Latin1_general_CI_AI
--declare temp @TEMP3
DECLARE @TEMP3 TABLE (name varchar(max))
--insert into @temp 3 only the data that are similar to our search name so as not to loop over all the data in the view
INSERT INTO @TEMP3(name)
select name from getalldata where SOUNDEX(name) LIKE SOUNDEX(@name)
--get the approximate count using the [DEMLEV] function.
--this function uses the Damerau levenshtein distance algorithm to calculate the distinct between the search string
--and the names inserted into @temp3 above. Uses frequency 2 so as to eliminate all the others
select @approximateMatch = count(1) from @TEMP3 where
dbo.[DamLev](replace(name,',',''),@name,@frequency) <= @frequency and
dbo.[DamLev](replace(name,',',''),@name,@frequency) > 0 and name != @name
--insert into @temp1 at end of every loop results
insert into @TEMP1 (fullname,approxMatch, exactmatch) values(@name,@approximateMatch,@exactMatch)
insert into FileUploadNameInsert (name) values (@name + ' ' +cast(@approximateMatch as varchar) + ' ' + cast(@exactMatch as varchar) + ', ' + cast(@transID as varchar) )
DELETE FROM @TEMP WHERE ID= @ID
delete from @TEMP3
END
--Return all the data stored in @temp3
select fullname,exactmatch,approxMatch, @transID as transactionID from @TEMP1
GO
最佳答案
在我看来,
使用Openrowset直接将记录读入数据库的预定义,正确索引的表中。
现在,使用预定义的存储过程在后端使用此表执行操作。
30,000行大约需要15分钟。