sql - 处理只有 30,000 行的 Excel 文件中的慢速 MSSQL 存储过程

标签 sql sql-server stored-procedures

我有一个带有 iterface 的网络应用程序,用户可以在上面上传文件。 excel文件中的数据被收集、连接并传递给
处理和返回数据的存储过程。
存储过程的简要说明。

存储过程收集字符串,使用分隔符将其分解并将其存储在临时变量表​​中。

另一个进程通过临时表运行,其中通过比较每个字符串进行计数以找到精确匹配计数和近似匹配计数
反对一个包含
第一行中每一行要比较的所有名称

例如,精确匹配计数是在 View 中找到 eact 字符串的位置.. (Bobby Bolonski )
使用频率为 2 的 levenshtein 距离算法数据库函数进行近似匹配。
temo 表@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 分钟。

    关于sql - 处理只有 30,000 行的 Excel 文件中的慢速 MSSQL 存储过程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38643707/

    相关文章:

    sql - 在日期之间进行选择的存储过程?

    sql - 一行中多个表的值

    sql-server - 使用 PIVOT 时无法在 SQL Server 2012 中获取正确的 SUM 值

    SQL命令未正确结束立即执行

    android - 将数据从android应用程序发送到服务器

    SQL - EXISTS 未引入子查询

    sql-server - 无法在 AspNetUsers 表中插入用户

    sql - 在 LEFT OUTER JOIN 中使用存储过程返回 SETOF 记录

    mysql - 仅当值不存在时返回行

    mysql - 如何按同时具有选择和计数的字段进行分组