Script beschleunigen...

  • VB.NET

Es gibt 11 Antworten in diesem Thema. Der letzte Beitrag () ist von lilienthal63.

    Script beschleunigen...

    Hallo in die VB-Runde!

    Folgende Frage:

    Ich habe ein Script, dass den Quelltext einer Webseite ausliest und in weiterer Folge diesen in eine Tabelle abspeichert. Dabei wird der Quelltext in seine Zeilen zerlegt.

    Da die Trennzeichen im Quelletext vorhanden sind gehe ich den String in einer Schleife zeichenweise durch bis zum nächsten Zeilenumbruch (chr(10) und (chr13) und schreibe dann den String in eine Tabelle mit dem Feld TAG und nummeriere die Zeilen in dem Feld TAG_NR mit eins beginnend bis zu letzten Zeile durch.

    Das Ganze mache ich mit einer SQL - Insert into.... Anweisung in jedem Loop. Dabei wird jedesmal die Datenbank connected und danach wieder getrennt. Und ich glaube dadurch braucht der Script auch etwas lange (20-30 Sekunden).

    Gitb es eine andere Möglichkeit in einer Schleife Daten in eine Tabelle zu schreiben, ohne für jeden zu schreibenden Datensatz eine Verbindung aufzubauen und dann wieder zu trennen?

    Ursprünglich lief der Script in einer Access-DB und da bin ich ja permanent mit der DB verbunden und brauchte nur mit docmd.runsql die Daten zu schreiben. Das ging ziemlich ruck zuck.
    Danke für die Antworten!

    Werde das Öffnen und Schliessen der DB aus der Schleife entfernen. Und vor Beginn der Schleife die DB-connecten und nach der Schleife schließen.

    Bulkinsert kenne ich nicht. Habe nach kurzer Befragung von Herrn Google erfahren, dass das für den MAssenimport von Daten verwendet wird. Gibt es irgendwo ein leicht verständliches Beispiel zu finden?

    LG
    also glaub 5000 Datensätze sollteman problemlos schneller als in 0,5 Sekunden abspeichern können.
    Mach dir halt ein DBCommand mit DBParametern, und in der Schleife das Command mit immer neuen Parametern ausführen.
    Anders wirds ein DataAdapter auch nicht machen, und die sind halt so flott wie oben angegeben.

    gugge vlt auch DbParameter verwenden
    Habe das Connecten und Close aus der Schleife verbannt und jetzt läuft das Script in geschätzten 0,419 Sekunden ;)

    Möchte das mit den DbParametern aber kapieren!

    Darum einmal DANKE an ErfinderDesRades für den Link. Allerdings fehlt mit der Bezug zu dem Beispiel. :( Ich möchte das aber verstehen.

    Ich poste einmal meinen Code der den HTML-String in die Tabelle schreibt. Wenn die Möglichkeit besteht und man kann den Code mit DbParametern ausführen, wäre ich dankbar, wenn mir jemand dabei unter die Arme greift :) Einmal die Syntax am eigenen Beispiel kapiert, sollte es bei anderen ja kein Problem mehr sein (hoffentlich).

    VB.NET-Quellcode

    1. Imports System.Data.OleDb
    2. Public Class FORM_WEB
    3. Dim CONNSTR As New OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=|DataDirectory|\FLIGHT_BOOK_D.mdb")
    4. Private Sub EXECNQ(ByVal CMDTXT As String)
    5. Dim CMD As New OleDbCommand(CMDTXT, CONNSTR)
    6. Try
    7. CMD.ExecuteNonQuery()
    8. Catch ex As Exception
    9. MessageBox.Show(ex.Message)
    10. End Try
    11. End Sub
    12. Private Sub B_IMPORT_Click(sender As System.Object, e As System.EventArgs) Handles B_IMPORT.Click
    13. Dim STR As String
    14. Dim CHECK As Integer
    15. Dim P1 As Integer
    16. Dim P2 As Integer
    17. Dim P3 As Integer
    18. Dim ZEICHEN As String
    19. Dim ANF As String
    20. Dim ANZ1 As Integer
    21. If Not Me.WebBrowser1.Document.Body Is Nothing Then
    22. STR = Me.WebBrowser1.Document.Body.InnerHtml
    23. ANZ1 = Len(STR)
    24. MsgBox(ANZ1)
    25. CHECK = InStr(1, STR, "PIREP-Details", vbTextCompare)
    26. If CHECK > 1000 Then
    27. CONNSTR.Open()
    28. Dim SQL As String = "DELETE t_BASIS.* FROM t_BASIS;"
    29. EXECNQ(SQL)
    30. P1 = 1
    31. P2 = 1
    32. P3 = 1
    33. ZEICHEN = ""
    34. ANF = ""
    35. Do Until P2 > ANZ1 - 200
    36. Do Until ANF = Chr(13)
    37. ANF = Mid(STR, P1, 1)
    38. ZEICHEN = ZEICHEN & ANF
    39. P1 = P1 + 1
    40. Loop
    41. ZEICHEN = Trim(ZEICHEN)
    42. ZEICHEN = Replace(ZEICHEN, Chr(13), "")
    43. ZEICHEN = Replace(ZEICHEN, Chr(10), "")
    44. SQL = "insert into t_BASIS(TAG,NR) values('" & ZEICHEN & "', " & P3 & ")"
    45. EXECNQ(SQL)
    46. ANF = ""
    47. ZEICHEN = ""
    48. P2 = P1
    49. P3 = P3 + 1
    50. Loop
    51. CONNSTR.Close()
    52. MessageBox.Show("alles impüp!§")
    53. Else
    54. MsgBox("Um einen Flug zu importieren, loggen Sie sich mit ihren Zugangsdaten ein." & Chr(13) & Chr(13) & "Dann wählen Sie Logbuch -> Meine Flüge -> und wählen einen Flug in der Detailansicht aus!", MsgBoxStyle.Information, FBV_TITEL)
    55. Exit Sub
    56. End If
    57. End If
    58. End Sub
    59. End Class


    Ich entschuldige mich vorab für den vielleicht etwas umständlichen Code, aber er funktioniert.

    DANKE im Voraus!
    Bitte VB-Tag benutzen - aber richtig - die Einrückungen sind wichtig.

    zu den DBParametern:
    Zunächst mal ist wohl leicht zu verstehen, dass du keine verwendest. Stattdessen bastelst du einen Sql-String, der die unterschiedlichen Werte im String eingefrickelt hat - eben wie mans nicht machen sollte.

    Aber ich merke grad, dass meine Extension auf deinen Fall nicht gut anwendbar ist, weil bei mir ja auch für jedes Ausführen ein neues Command generiert würde. Die Extension ist halt eher für Selects gedacht, wo man mit einer Ausführung gleich viele Datensätze abholt.

    In deinem Fall wäre das Command aber vielfach wiederverwendbar, man müsste es allerdings vorm Eintritt in den Loop erzeugen, und mit geeigneten DBParametern bestücken. Im Loop weist man dann die Werte an DBParam.Value zu, und fährt dann dasselbe Command immer wieder ab.
    Ich bin jetzt aber zu faul, es dir zu coden - sorry.

    vlt. hilfts, wenn du dir im ObjectBrowser/ObjektKatalog mal die OleDBCommand-Klasse anguckst, und von da auch zu den OleDbParametern weiterbrausen tust.
    Danke für dein Feedback!

    Zu den Einrückungen - habe ich jetzt erst gesehen, dass die beim Kopieren nicht übernommen wurden. Im Origignal sind diese vorhanden, da ja sonst die Übersicht ein wenig kontraproduktiv wird :)

    Das mit dem Code ist kein Problem! Das das Ganze nicht so ist wie es sein soll, weiß ich. Aber es funktioniert und darüber bin ich erst einmal froh. Bin aber total an den DbPArametern interessiert. Werde nochmals deinen Link durchstöbern, vielleicht springt ja der Funken über...

    DANKE nochmals und LG
    also wenn du mit der Extension-Methode arbeitest, sähe es vlt. so aus:

    VB.NET-Quellcode

    1. 'SQL = "insert into t_BASIS(TAG,NR) values('" & ZEICHEN & "', " & P3 & ")"
    2. 'EXECNQ(SQL)
    3. '(_Conn = Connection)
    4. _Conn.CreateCommandX( "insert into t_BASIS(TAG,NR) values(?, ?)", ZEICHEN, P3).ExecuteNonQuery()
    schoma leserlicher, und .CreateCommandX verwendet DbParameter.
    Aber wie auch bei deim Code würde hierbei in jedem Loop ein neues Command-Objekt erzeugt (und übrigens nicht wieder freigegeben), was eiglich recht suboptimal ist.