2016-07-28 9 views
4

Ich habe eine Web-Anwendung mit einem Iterface, dass Benutzer Dateien hochladen können. Die Daten der Excel-Datei werden gesammelt, verkettet und an eine gespeicherte Prozedur, die Daten verarbeitet und zurückgibt, an übergeben. Eine kurze Erläuterung der gespeicherten Prozedur.Verlangsamen MSSQL gespeicherte Prozedur in Prozessen Excel-Dateien mit nur 30.000 Zeilen

Die gespeicherte Prozedur erfasst die Zeichenfolge, bricht sie mit einem Delimeter ab und speichert sie in einer Temp-Variablentabelle.

ist Ein weiterer Prozess Trog die temporäre Tabelle ausführen, wo eine Zählung durch die genaue Anzahl und die ungefähre Anzahl zu finden Vergleichen jeder Zeichenfolge erfolgt agains eine Ansicht, die in der für jede Zeile vergleichen gegen alle Namen enthält erste

eine genaue Anzahl ist, wo die EACT Zeichenfolge beispielsweise in der Ansicht .. (Bobby Bolonski) eine ungefähre Übereinstimmung eine levenshtein Distanz Algorithmus Datenbankfunktion mit einer Frequenz von 2
temo Tabelle erfolgt gefunden wird @temp1.

Das Ergebnis (Name, exactmatch count und approximate match count) wird in der endgültigen Temp-Tabelle gespeichert.

eine select-Anweisung auf der letzten temporären Tabelle ausgeführt wird, um alle Daten zu der Anwendung zurückzukehren ..

Mein Problem ist, dass, wenn ich bestehen große Dateien wie und Excel-Datei mit 27.000 Namen. Die Verarbeitung und Rückgabe der Daten aus der Datenbank dauerte 2 Stunden.

Ich habe beide Server überprüft, wo die Anwendung läuft und wo die Datenbank läuft. Auf dem Anwendungsserver. Die Speicher- und CPU-Auslastung beträgt weniger als 15%. Auf dem Datenbankserver. Sowohl die Speicher- als auch die CPU-Nutzung betragen weniger als 15%.

Ich suche Ratschläge, welche Verbesserungen ich machen kann, um den Prozess schneller zu machen.

Unten ist die Kopie der gespeicherten Prozedur, da sie alle Arbeit erledigt und die Ergebnisse an die Webanwendung zurückgibt.

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 
+1

Können Sie den Code von FnSplitTest ausgeben? Excel-Blatt ist CSV oder XLS-Erweiterung, wie man es lädt? –

+1

Zuerst müssen Sie den Schuldigen finden, der die Anwendung verlangsamt. Importieren Sie CSV, fügen Sie Daten in Temp Table oder Processing Records ein. Die Verarbeitung von Datensätzen ist ziemlich einfach. Ich würde immer noch empfehlen, aber das ist der nächste Schritt. – AVK

+0

haben Sie Ihren Ausführungsplan angesehen, diese ersetzt und Ihre Funktionen und ähnliche Anweisungen und Temp-Tabes sehen ziemlich gruselig aus –

Antwort

0

Meiner Meinung nach,

  1. Verwenden Openrowset lesen direkt die Datensätze in einer vordefinierten, korrekt indiziert Tabelle Ihrer Datenbank.

  2. Führen Sie Ihre Operationen jetzt mithilfe dieser Tabelle im Back-End unter Verwendung vordefinierter gespeicherter Prozeduren aus.

Es sollte etwa 15 Minuten für 30.000 Zeilen dauern.