Seite 1 von 2

CloseDatabase dauert extrem lang

Verfasst: 15.01.2012 12:10
von - chris -
Hallo

Das schliessen einer Datenbank dauert extrem lang (~10Sek).
Woran könnte das liegen, lässt sicht daran etwas ändern?

Code: Alles auswählen


EnableExplicit

Define modnr_DB$, SQL.s, col.i, zeile$, spalte$, n.i, modnr_row.i
Define t1.q, t2.q, time.q

If UseODBCDatabase() = 0
  End
EndIf

t1 = timeGetTime_()

modnr_DB$ = "als_121"

If OpenDatabase(0, modnr_DB$, "", "", #PB_Database_ODBC)

  t2 = timeGetTime_()
  Debug "OpenDatabase: " + Str(t2 - t1) + " ms"

  SQL = "SELECT MODNR,TEXT1,TEXT2 FROM MODST ORDER BY MODNR;"
  If DatabaseQuery(0, SQL)

    t2 = timeGetTime_()
    Debug "DatabaseQuery: " + Str(t2 - t1) + " ms"

    If CreateFile(0, "modnr_export.txt")

      t2 = timeGetTime_()
      Debug "CreateFile: " + Str(t2 - t1) + " ms"

      col = DatabaseColumns(0)
      ;Debug "col: " + Str(col)

      zeile$ = ""
      For n = 0 To col - 1
        spalte$ = DatabaseColumnName(0, n)
        zeile$  = zeile$ + spalte$
        If n < col - 1
          zeile$ = zeile$ + ";"
        EndIf
      Next n
      ;Debug zeile$
      WriteStringN(0, zeile$)

      t2 = timeGetTime_()
      Debug "DatabaseColumnName: " + Str(t2 - t1) + " ms"

      modnr_row = 0
      While NextDatabaseRow(0)
        modnr_row = modnr_row + 1
        zeile$    = ""
        For n = 0 To col - 1
          spalte$ = Trim(GetDatabaseString(0, n))
          zeile$  = zeile$ + spalte$
          If n < col - 1
            zeile$ = zeile$ + ";"
          EndIf
        Next n
        ;Debug zeile$
        WriteStringN(0, zeile$)
      Wend

      t2 = timeGetTime_()
      Debug "NextDatabaseRow: " + Str(t2 - t1) + " ms"

      CloseFile(0)

      t2 = timeGetTime_()
      Debug "CloseFile: " + Str(t2 - t1) + " ms"

    EndIf

    FinishDatabaseQuery(0)

    t2 = timeGetTime_()
    Debug "FinishDatabaseQuery: " + Str(t2 - t1) + " ms"

  EndIf

  CloseDatabase(0)

  t2 = timeGetTime_()
  Debug "CloseDatabase: " + Str(t2 - t1) + " ms"

EndIf

Debug "modnr_row: " + Str(modnr_row)

End

Hier die Ausgabe dazu:

Code: Alles auswählen


OpenDatabase: 37 ms
DatabaseQuery: 56 ms
CreateFile: 56 ms
DatabaseColumnName: 57 ms
NextDatabaseRow: 60 ms
CloseFile: 61 ms
FinishDatabaseQuery: 61 ms
CloseDatabase: 10026 ms
modnr_row: 621


Re: CloseDatabase dauert extrem lang

Verfasst: 15.01.2012 13:11
von ts-soft
- chris - hat geschrieben: Woran könnte das liegen, lässt sicht daran etwas ändern?
Am Debugger? Ohne Debugger messen.

Deine Meßergebnisse mit angeschalteten Debugger haben keinerlei Aussagefähigkeit!
Die meiste Zeit verbraucht der Debugger und den Rest die AV, die gerne Dateien
überpüft, wenn der Debugger läuft.

Teste das ganze bitte ohne jeglichen Debugger und prüfe dann die Ergebnisse, die
jetzigen Ergebnisse sind absolut unnütz :wink:

Gruß
Thomas

Re: CloseDatabase dauert extrem lang

Verfasst: 15.01.2012 13:52
von Kiffi
ts-soft hat geschrieben:Am Debugger? Ohne Debugger messen.
@- chris -:

überdies solltest Du t1 korrekt vor dem jeweiligen Befehl (und nicht nur am Anfang des Codes) setzen:

Code: Alles auswählen

  t1 = timeGetTime_()
  CloseDatabase(0)
  t2 = timeGetTime_()
Grüße ... Kiffi

Re: CloseDatabase dauert extrem lang

Verfasst: 15.01.2012 13:57
von - chris -
Hallo

Wenn ich t1 nur am Anfang einmal setze
bekomme ich doch immer die Zwischenzeiten
und am Ende die Gesamtzeit.

Auch ohne Debugger dauert es 10 Sekunden.
Habe den Debugger ausgeschaltet und am Ende
folgendes eingefügt:

Code: Alles auswählen

MessageRequester("Test", Str(t2-t1) + " ms")

Hier bei diesen Programm ist es mir ja aufgefallen,
das das ganze sehr lange dauert.

Die Text-Datei ist schon lange fertig und die Ausgabe
von "modnr_row" kommt erst später.

Das Programm habe ich als EXE laufen gehabt.

Am Anfang des Export's habe ich
t1 = timeGetTime_()
am Ende dann
t2 = timeGetTime_()
time = t2 - t1
und time ergibt die Gesamtzeit.

Code: Alles auswählen


EnableExplicit

;#program_test = 1

If UseODBCDatabase() = 0
  End
EndIf

;- Enumerations / DataSections
;- Windows
Enumeration
  #Window_0
EndEnumeration

;- Gadgets
Enumeration
  #String_db
  #String_row
  #Button_export
  #Button_break
  #StatusBar
EndEnumeration

;- Fonts
Enumeration
  #Arial10
EndEnumeration

;- Global
Global path$, quit.i, q1.i, q2.i, quit_export.i, exportTH.i, dateTH.i

;- Define
Define Event.i, EventWindow.i, EventGadget.i, EventType.i, EventMenu.i

LoadFont(#Arial10, "Arial", 10, #PB_Font_HighQuality | #PB_Font_Bold)

CompilerIf Defined(program_test, #PB_Constant)
  path$ = ""
CompilerElse
  path$ = GetPathPart(ProgramFilename())
CompilerEndIf

Procedure export_modnr(temp.i)

  Protected modnr_DB$, SQL.s, col.i, zeile$, spalte$, n.i, modnr_row.i
  Protected t1.q, t2.q, time.q

  If quit = 0
    modnr_DB$ = Trim(GetGadgetText(#String_db))
    SetGadgetText(#String_row, "***")
    StatusBarText(#StatusBar, 1, "0 ms", #PB_StatusBar_Right)
  EndIf

  t1 = timeGetTime_()

  If modnr_DB$ <> ""

    If OpenDatabase(0, modnr_DB$, "", "", #PB_Database_ODBC)

      SQL = "SELECT MODNR,TEXT1,TEXT2 FROM MODST ORDER BY MODNR;"
      If DatabaseQuery(0, SQL)

        If CreateFile(0, path$ + "modnr_export.txt")

          col = DatabaseColumns(0)

          zeile$ = ""
          For n = 0 To col - 1
            spalte$ = DatabaseColumnName(0, n)
            zeile$  = zeile$ + spalte$
            If n < col - 1
              zeile$ = zeile$ + ";"
            EndIf
          Next n
          WriteStringN(0, zeile$)

          modnr_row = 0
          While NextDatabaseRow(0)
            modnr_row = modnr_row + 1
            zeile$    = ""
            For n = 0 To col - 1
              spalte$ = Trim(GetDatabaseString(0, n))
              spalte$ = ReplaceString(spalte$, ";", " ")
              zeile$  = zeile$ + spalte$
              If n < col - 1
                zeile$ = zeile$ + ";"
              EndIf
            Next n
            WriteStringN(0, zeile$)
            If quit_export = 1
              Break
            EndIf
          Wend

          CloseFile(0)

        EndIf

        FinishDatabaseQuery(0)

      EndIf

      CloseDatabase(0)

    EndIf

  EndIf

  t2 = timeGetTime_()

  time = t2 - t1

  If quit = 0
    SetGadgetText(#String_row, Str(modnr_row))
    StatusBarText(#StatusBar, 1, Str(time) + " ms", #PB_StatusBar_Right)
  EndIf

  quit_export = 0

EndProcedure

Procedure status_date(temp.i)

  Protected date$, n.i

  Repeat

    date$ = FormatDate("%dd.%mm.%yyyy %hh:%ii:%ss", Date())

    If quit = 0
      StatusBarText(#StatusBar, 0, date$, #PB_StatusBar_Center)
    EndIf

    For n = 1 To 10
      If quit = 1
        Break
      EndIf
      Delay(100)
    Next n

  Until quit = 1

EndProcedure

Procedure OpenWindow_Window_0()

  Protected res.i

  res = #False

  If OpenWindow(#Window_0, 578, 205, 210, 187, "MODNR", #PB_Window_SystemMenu | #PB_Window_MinimizeGadget | #PB_Window_TitleBar)

    StringGadget(#String_db, 30, 20, 150, 30, "als_121", #PB_Text_Center)
    StringGadget(#String_row, 30, 60, 150, 30, "***", #PB_Text_Center)
    ButtonGadget(#Button_export, 30, 110, 70, 35, "Export")
    ButtonGadget(#Button_break, 110, 110, 70, 35, "Abbrechen")

    SetGadgetFont(#String_db, FontID(#Arial10))
    SetGadgetFont(#String_row, FontID(#Arial10))

    If CreateStatusBar(#StatusBar, WindowID(#Window_0))
      AddStatusBarField(130)
      AddStatusBarField(80)
      res = #True
    EndIf

  EndIf

  ProcedureReturn res
EndProcedure

If OpenWindow_Window_0()

  StatusBarText(#StatusBar, 1, "0 ms", #PB_StatusBar_Right)

  dateTH = CreateThread(@status_date(), 0)

  ;- Event loop
  Repeat

    Event       = WaitWindowEvent(100)
    EventGadget = EventGadget()
    EventType   = EventType()
    EventWindow = EventWindow()

    Select Event

      Case #PB_Event_Gadget

        If EventGadget = #String_db

        ElseIf EventGadget = #String_row

        ElseIf EventGadget = #Button_export

          If IsThread(exportTH) = 0
            exportTH = CreateThread(@export_modnr(), 0)
          EndIf

        ElseIf EventGadget = #Button_break

          If IsThread(exportTH) = 1
            quit_export = 1
          EndIf

        EndIf

      Case #PB_Event_CloseWindow

        quit_export = 1

        quit = 1

    EndSelect

    q1 = IsThread(exportTH)
    q2 = IsThread(dateTH)

  Until quit = 1 And q1 = 0 And q2 = 0

EndIf

End


Re: CloseDatabase dauert extrem lang

Verfasst: 15.01.2012 14:10
von ts-soft

Code: Alles auswählen

          If IsThread(exportTH) = 1
            quit_export = 1
          EndIf
Das = 1 ist wohl verkehrt! Entweder weglassen oder auf <> 0 testen.

Testen kann ich Deinen Code leider nicht, müßte erst den ODBC-Manager finden und dann noch Wissen welchen
Treiber Du überhaupt nutzt.

IMHO wird es nicht an PB liegen, wenn das schließen so lange dauert, aber ungetestet, ist mir jetzt ehrlich gesagt
zu umständlich.

Gruß
Thomas

Re: CloseDatabase dauert extrem lang

Verfasst: 15.01.2012 14:38
von - chris -
Hallo

Ein einfacher Test zeigt, das funktioniert:

Code: Alles auswählen


If IsThread(exportTH) = 1
  Debug "quit_export"
  quit_export = 1
EndIf

Das wollte ich einbauen, damit man das exportieren vorzeitig beenden kann.

Hier bei der "While NextDatabaseRow(0)" Schleife,
das funktionierte aber nicht, weil ja das Programm bei CloseDatabase hängt.

Code: Alles auswählen


          While NextDatabaseRow(0)
            modnr_row = modnr_row + 1
            zeile$    = ""
            For n = 0 To col - 1
              spalte$ = Trim(GetDatabaseString(0, n))
              spalte$ = ReplaceString(spalte$, ";", " ")
              zeile$  = zeile$ + spalte$
              If n < col - 1
                zeile$ = zeile$ + ";"
              EndIf
            Next n
            WriteStringN(0, zeile$)
            If quit_export = 1
              Break
            EndIf
          Wend


Re: CloseDatabase dauert extrem lang

Verfasst: 15.01.2012 14:53
von ts-soft
- chris - hat geschrieben:Hallo

Ein einfacher Test zeigt, das funktioniert:
purebasic.chm hat geschrieben:Das 'Ergebnis' ist Null falls es kein gültiger Thread war, oder falls er bereits beendet wurde.
Ein einfacher Blick in der Hilfe sagt mir: Null oder <> Null, somit ist Dein Test keine Garantie :mrgreen:

Da PB lediglich dem ODBC-Treiber sagt, er möchte die DB schliessen, sollte es IMHO am ODBC-Treiber liegen,
da dieser das schliessen ja ausführt und nicht PB.

Re: CloseDatabase dauert extrem lang

Verfasst: 15.01.2012 15:20
von - chris -
Hallo

Das auf <> 0 vergleichen ist natürlich besser.

Die Datenbank ist Interbase, zugriff erfolgt über Netzwerk mit dem
Firebird ODBC-Treiber.

Hab das ganze jetzt mal lokal ausprobiert und dann werden die 621
Datensätze in 40ms exportiert.

Re: CloseDatabase dauert extrem lang

Verfasst: 15.01.2012 15:35
von ts-soft
- chris - hat geschrieben: Die Datenbank ist Interbase, zugriff erfolgt über Netzwerk mit dem
Firebird ODBC-Treiber.
Das sind doch wichtige Informationen, die Du uns vorenthalten hast. Hätte ich mir
jetzt einen Testcode gebastelt, hätte ich mich jetzt dumm und dämlich geärgert,
wegen der Zeitverschwendung <)

Bei zugriffen über das Netzwerk sind die von Dir gemessenen Werte ja nicht so
abwegig. Wie man das jetzt ändern kann, weiß ich leider auch nicht, aber durch
Änderung im PB-Code wirste da wohl nicht viel erreichen können.

Gruß
Thomas

Re: CloseDatabase dauert extrem lang

Verfasst: 15.01.2012 15:40
von - chris -
Hallo

Hier bei dem Test hängt es auch schon:

Code: Alles auswählen


If UseODBCDatabase() = 0
  End
EndIf

If OpenDatabase(0, "als_127", "", "", #PB_Database_ODBC)
  
  Debug "OpenDatabase"

  CloseDatabase(0)  
  
  Debug "CloseDatabase"
  
EndIf