webForumDet fria alternativet

Skriver till databasen långsamt...

ASP

3 svar · 354 visningar · startad av devotion

Medlem sedan jan. 20013 582 inlägg
Frågan#1

Hej! :(

Jag har följande kod, som visserligen fungerar, men är väldigt långsam....

<%@LANGUAGE="VBSCRIPT" CODEPAGE="1252"%>
<% Option Explicit %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>Untitled Document</title>
</head>

<body>

<%
Dim sSQL, objConn, objRS1, objRS2,  iStatus, sNote, sCategory, sName, sArtNr, sUnit, iPrice, iNextId, sArticleNumber, sArticleName, sList, iSupplierId, dStartTimer, totalTime, iCounter

'Starta timern
dStartTimer = timer()

'Nollställa räknare
iCounter = 0

'Ange status; 0 = "synkroniserad med SPCS", 1 = "Inte synkroniserad mot SPCS"
iStatus = 0

'Notering
sNote = ""
'Pris
iPrice = 0

' Öppna databasen
' ***************
Set objConn = Server.CreateObject("ADODB.Connection")
objConn.ConnectionString = Application("sConn")
objConn.Open

sSQL = 		"SELECT tblArticle.articlenumber, tblArticle.articleName, tblArticle.articleUnit " &_
			"FROM tblArticle " &_
			"ORDER BY tblArticle.articlenumber"
			
Set objRS1 = Server.CreateObject("ADODB.Recordset")
objRS1.Open sSQL, objConn, 3, 1

If not objRS1.EOF then

' Räkneverk
' *********
Response.write("<div id=""message"">Vänta, skriver till databasen...</div>")
Response.write("<div id=""progress""></div>")
Response.Flush()
	
	do while not objRS1.EOF
	
		' Villkor för att flusha
		' **********************
		iCounter = iCounter +1
		if iCounter mod 10 = 0 then
			Response.write ("<script>document.getElementById(""progress"").innerHTML=""" & iCounter & """;</script>")
			Response.flush
		end if
	
		sArticleNumber = objRS1("articleNumber")
		sArticleName = objRS1("articleName")
		sUnit = lCase(objRS1("articleUnit"))
		
		'Ta ut de två första tecknena i E-numret
		sList = left(sArticleNumber, 2)
		
		'Hämta kategorinamn mha sList
		Set objRS2 = objConn.Execute ("SELECT listName FROM tblList WHERE listNr = '" & sList & "'")
		
		If not objRS2.EOF then	
			sCategory = objRS2("listName")	
		End If

		objRS2.Close
		Set objRS2 = Nothing
		
		Set objRS2 = objConn.Execute ("SELECT nextId FROM UppdragNu.dbo.tblNextId WHERE [table] = 'tblArticle'")
		
		If not objRS2.EOF then	
			iNextId = cLng(objRS2("NextId")) 	
		End If
				
		objRS2.Close
		Set objRS2 = Nothing
		
		
		sSQL = 	"INSERT INTO UppdragNu.dbo.tblArticle ([Id], [Status], [Modified], [Nr], [Name], [Category], [Unit], [Price], [Note]) " &_
				"VALUES(" & iNextId & ", " & iStatus & ", getdate(), '" & sArticleNumber & "', '" & sArticleName & "', " &_
				"'" & sCategory & "', '" & sUnit & "', " & iPrice & ", '" & sNote & "')"
	
		objConn.execute sSQL,,128
		

		sSQL = "UPDATE UppdragNu.dbo.tblNextId SET nextId = nextId + 1 WHERE [Table] = 'tblArticle'"
		objConn.Execute sSQL,, 128
	
		objRS1.Movenext
	
	Loop

'Skriv ut att artiklarna lagrats
Response.write("<script>document.getElementById(""message"").innerHTML=""Datat har lagrats i databasen! "";</script><br><br>")

'Skriv ut timern
totalTime = timer() - dStartTimer
Response.Write FormatMinSec(totalTime) & "<br><br>"

'Stänga objRS1
objRS1.Close
Set objRS1 = Nothing

Else
	Response.write "Fel!"	
End if

%>
</body>
</html>

Har jag gjort något galet?

Jag kan inte hitta några fel. Jag har gjort liknande innan utan problem.... Det enda som skiljer är att jag arbetar med två databaser....

Kan det dra ner hastigheten.. eller har jag gjort en blunder?

Edit/ Databas MS SQL-server
Mvh
Henrik

Medlem sedan dec. 19996 721 inlägg
#2

Om det inte hade varit för id-numret som du hämtar från tblNextId så hade du kunnat göra hela importen med en enda SQL-sats (INSERT INTO .... SELECT ...), men som det är nu är det i princip rätt.

Det verkar vara en rutin som körs under kontrollerade former, så du skulle kunna nöja dig med att hämta ut värdet från tblNextId en enda gång, och uppdatera tblNextId en enda gång. Du vet ju att räknaren ökar med 1 för varje varv.

Kategorinamnet går att hämta ut i första frågan.

SELECT a.articlenumber, a.articleName, a.articleUnit, l.listName 
FROM tblArticle a
LEFT JOIN tblList l ON LEFT(a.articleNumber,2)=l.listNr 
ORDER BY a.articlenumber

Och ja, man förlorar en del prestanda på att jobba över databasgränsen. Hur mycket är svårt att sia om.

Medlem sedan jan. 20013 582 inlägg
#3

Tack för det emission....

Kankse något sådant här:

<%
Dim sSQL, objConn, objRS1, objRS2,  iStatus, sNote, sCategory, sName, sArtNr, sUnit, iPrice, iNextId, sArticleNumber, sArticleName, sList, iSupplierId, dStartTimer, totalTime, iCounter

'Starta timern
dStartTimer = timer()

'Nollställa räknare
iCounter = 0

'Ange status; 0 = "synkroniserad med SPCS", 1 = "Inte synkroniserad mot SPCS"
iStatus = 0

'Notering
sNote = ""
'Pris
iPrice = 0

' Öppna databasen
' ***************
Set objConn = Server.CreateObject("ADODB.Connection")
objConn.ConnectionString = Application("sConn")
objConn.Open

'Hämta nästa Id
Set objRS = objConn.Execute ("SELECT nextId FROM UppdragNu.dbo.tblNextId WHERE [table] = 'tblArticle'")
		
If not objRS.EOF then	
	iNextId = cLng(objRS("NextId")) 	
End If
		
objRS.Close
Set objRS = Nothing

sSQL = 		"SELECT a.articlenumber, a.articleName, a.articleUnit, l.listName " &_
			"FROM tblArticle a " &_
			"LEFT JOIN tblList l ON LEFT(a.articleNumber,2)=l.listNr " &_
			"ORDER BY a.articlenumber"
			
Set objRS = Server.CreateObject("ADODB.Recordset")
objRS.Open sSQL, objConn, 3, 1

If not objRS.EOF then

' Räkneverk
' *********
Response.write("<div id=""message"">Vänta, skriver till databasen...</div>")
Response.write("<div id=""progress""></div>")
Response.Flush()
	
	do while not objRS.EOF
	
		' Villkor för att flusha
		' **********************
		iCounter = iCounter +1
		if iCounter mod 10 = 0 then
			Response.write ("<script>document.getElementById(""progress"").innerHTML=""" & iCounter & """;</script>")
			Response.flush
		end if
	
		sArticleNumber = objRS("articleNumber")
		sArticleName = objRS("articleName")
		sUnit = lCase(objRS("articleUnit"))
		sCategory = objRS("listName")	
	
		sSQL = 	"INSERT INTO UppdragNu.dbo.tblArticle ([Id], [Status], [Modified], [Nr], [Name], [Category], [Unit], [Price], [Note]) " &_
				"VALUES(" & iNextId & ", " & iStatus & ", getdate(), '" & sArticleNumber & "', '" & sArticleName & "', " &_
				"'" & sCategory & "', '" & sUnit & "', " & iPrice & ", '" & sNote & "')"
	
		objConn.execute sSQL,,128
		
		iNextId = iNextId + 1
			
		objRS.Movenext
	
	Loop

'Uppdatera tblNextId
sSQL = "UPDATE UppdragNu.dbo.tblNextId SET nextId = " & iNextId & " WHERE [Table] = 'tblArticle'"
		objConn.Execute sSQL,, 128

'Skriv ut att artiklarna lagrats
Response.write("<script>document.getElementById(""message"").innerHTML=""Datat har lagrats i databasen! "";</script><br><br>")

'Skriv ut timern
totalTime = timer() - dStartTimer
Response.Write FormatMinSec(totalTime) & "<br><br>"

'Stänga objRS
objRS.Close
Set objRS = Nothing

Else
	Response.write "Fel!"	
End if

%>

Har dock inte hunnit provköra än... Men det ser ju lite smidigare ut, och borde gå lite fortare...

Mvh
Henrik

Medlem sedan jan. 20013 582 inlägg
#4

Det verkar gå fortare.... Nu är det ju 200 000 artiklar som skall loopas ut, så visst tar det lite tid. Men detta är en operation som görs 3 gånger per år.

Inget annat som går att optimera i koden?

Mvh
Henrik

255 ms totalt · 4 externa anrop · v20260731065814-full.1dc6f849
121 ms — deklarationer (db)
0 ms — hämta statistik (cache)
132 ms — hämta tråd, inlägg och bilagor (db)
120 ms — ändringar (db)