Bartek Borczyk

Bartek Borczyk Operator liczb i
słów

Temat: OPTYMALIZACJA

Mam pewną procedurę, która:
- otwiera recordseta A (tabela; ok. 15000)
- przechodzi w pętli przez wszystkie jego rekordy

- przypisuje wartości do zmiennych na podstawie aktualnego wiersza
- otwiera recordseta B (sql1)
- jeżeli B jest niepusty (kilka-kilkanaście wierszy) to pobiera wartości i zapisuje je do A
- jeżeli B jest pusty to otwiera recordseta C (sql2)
- jeżeli C jest niepusty (kilka-kilkanaście wierszy) to pobiera wartości i zapisuje je do A
- jeżeli C jest pusty to przypisuje wartości domyślne i zapisuje do A

I teraz problem. Jeżeli wykonuję procedurę w takim schemacie trwa to ok. 20 minut. Jeżeli rozbiję test na dwie osobne pętle (dwa razy otwieram recordseta A testując najpierw dla sql1, potem dla sql2 z pominięciem tego, co znalazł w sql1), każda trwa po ok. 3-4 minuty a więc razem wychodzi nie więcej niż połowa z pierwszej metody. Ktoś wie dlaczego tak się dzieje.

Dodam, że zrobiłem sobie unaoczniający pasek postępu i różnica w prędkości jest oczywiście dobrze widoczna.

Recordset jest DAO.Bartosz Borczyk edytował(a) ten post dnia 19.10.09 o godzinie 07:01
Bartek Borczyk

Bartek Borczyk Operator liczb i
słów

Temat: OPTYMALIZACJA

Ciągnąc temat dalej.

Mam podobną sytuację.
- otwieram recordsetem (dbopentable) tabelę1 (ok. 10 tyś.); z niej ważnej jest jedno pole, które służy mi jako wartość where
- otwieram recordsetem (tu już próbowałem i dbopendynaset, i dbopensnapshot) kwerendę1 sql (dosłownie kilka wierszy) z tabeli2 ok. 200 tyś.; jeżeli jest niepusta to zapisuje z niej wartości do tabeli1, jeżeli jest pusta to zapisuje wartości domyślne.

I pętla idzie jak krew z nosa...
po 30 sekundach mam 63/9805 co daje 0,64% a do końca pozostaje 01:17:19 :(

Z dodatkowych informacji:
- mowa (niestety) o DAO
- kolumna, na którą zakładam where jest tekstowa
- najdłuższy string to ok. 200 znaków; skleiłem tu wartości z trzech innych kolumn (i tu może lepiej byłoby założyć where na każdą z tych kolumn z osobna?)
- w obu kolumnach mam założony indeks na kolumny kluczowe (nr tel)

Jakiś myk na dopalacz? Bo głupio, żeby to, co miało mi ułatwić robotę, przyprawiało o niezły w^*&% :)

Jak najszybciej robić takie rzeczy w accessie?

Nie robię tego joinem bo w obu tabelach mogą powtarzać się nr tel a nie chce, żeby mi się sztucznie zwiększała ilość rekordów.

Może łatwiej będzie ze źródłem:

Sub sPorównanie()
Dim dbsBieżąca As DAO.Database: Set dbsBieżąca = CurrentDb
Const strBazaGTI_Nazwa As String = "tblGTI_Baza"
Dim strBazaGTI_WyczyśćSQL As String
Dim rcsBazaGTI As DAO.Recordset
Dim lngBazaGTI_Ilość As Long
Dim lngBazaGTI_Licznik As Long

Dim dteBaza_DataUmowy As Date
Dim strBaza_NrTel As String

Dim strGTI_Sprzedaż As String
Dim intGTI_IlośćDok As String
Dim strGTI_Magazyn As String
Dim dteGTI_DataUmowy As Date
Dim strGTI_DatyDok As String
Dim strGTI_NrDok As String

Dim strSprzedażGTI_WybierzSQL As String
Dim rcsSprzedażGTI As DAO.Recordset
Dim intSprzedażGTI_Ilość As Integer

Dim dteCzasPoczątku As Date
Dim dteCzasBieżący As Date
Dim dteCzasRóżnica As Date
Dim dteCzasPozostały As Date

dteCzasPoczątku = Now

'czyszczenie porównania
strBazaGTI_WyczyśćSQL = "UPDATE tblGTI_Baza SET tblGTI_Baza.strGTI_Sprzedaż = Null, tblGTI_Baza.intGTI_IlośćDok = Null, tblGTI_Baza.strGTI_Magazyn = Null, tblGTI_Baza.dteGTI_DataUmowy = Null, tblGTI_Baza.strGTI_DatyDok = Null, tblGTI_Baza.strGTI_NrDok = Null;"

With DoCmd
.SetWarnings False
.RunSQL strBazaGTI_WyczyśćSQL
.SetWarnings True
End With

Set rcsBazaGTI = dbsBieżąca.OpenRecordset(strBazaGTI_Nazwa, dbOpenTable)
With rcsBazaGTI
If Not .EOF Then
.MoveLast
lngBazaGTI_Ilość = .RecordCount
.MoveFirst
End If

Do Until .EOF
'status
lngBazaGTI_Licznik = lngBazaGTI_Licznik + 1
SysCmd acSysCmdSetStatus, "Porównanie: " & lngBazaGTI_Licznik & "/" & lngBazaGTI_Ilość & " (" & Format(lngBazaGTI_Licznik / lngBazaGTI_Ilość, "Percent") & ")"

dteCzasBieżący = Now
dteCzasRóżnica = dteCzasBieżący - dteCzasPoczątku
dteCzasPozostały = dteCzasRóżnica / (lngBazaGTI_Licznik / lngBazaGTI_Ilość) - dteCzasRóżnica

Form_frmPanelKontrolny.prgPostęp.Value = (lngBazaGTI_Licznik / lngBazaGTI_Ilość) * 100
Form_frmPanelKontrolny.lblStaus.Caption = "Status: " & Format(lngBazaGTI_Licznik / lngBazaGTI_Ilość, "Percent") & " / Upłynęło: " & dteCzasRóżnica & " / Pozostało: " & dteCzasPozostały
DoCmd.RepaintObject acForm, Form_frmPanelKontrolny.Name

'wyzerowanie
strGTI_Sprzedaż = "NIE"
intGTI_IlośćDok = 999
strGTI_Magazyn = ""
dteGTI_DataUmowy = Empty
strGTI_DatyDok = ""
strGTI_NrDok = ""

'porównanie
strBaza_NrTel = .Fields("strBaza_NrTel").Value

If Len(strBaza_NrTel) > 0 Then
With rcsBazaGTI
.Edit
.Fields("strGTI_Sprzedaż").Value = strGTI_Sprzedaż
.Update
End With

'porównanie po numerze telefonu
strSprzedażGTI_WybierzSQL = "SELECT tblGTI_Sprzedaż.dteGTI_DataUmowy, tblGTI_Sprzedaż.strGTI_NrDok, tblGTI_Sprzedaż.strGTI_Magazyn " & _
"FROM tblGTI_Sprzedaż " & _
"WHERE (((tblGTI_Sprzedaż.strGTI_NrTel) Like 'strBaza_NrTel'))" & _
"ORDER BY tblGTI_Sprzedaż.dteGTI_DataUmowy;"

Set rcsSprzedażGTI = dbsBieżąca.OpenRecordset(strSprzedażGTI_WybierzSQL, dbOpenSnapshot)
With rcsSprzedażGTI
If Not .EOF Then
'.MoveLast
'intSprzedażGTI_Ilość = .RecordCount
'.MoveFirst

strGTI_Sprzedaż = "TAK"
intGTI_IlośćDok = intSprzedażGTI_Ilość
dteGTI_DataUmowy = .Fields("dteGTI_DataUmowy").Value

strGTI_Magazyn = .Fields("strGTI_Magazyn").Value
strGTI_DatyDok = CStr(.Fields("dteGTI_DataUmowy").Value)
strGTI_NrDok = .Fields("strGTI_NrDok").Value

Do Until .EOF
strGTI_Magazyn = strGTI_Magazyn & .Fields("strGTI_Magazyn").Value & "/"
strGTI_DatyDok = strGTI_DatyDok & CStr(.Fields("dteGTI_DataUmowy").Value) & "/"
strGTI_NrDok = strGTI_NrDok & .Fields("strGTI_NrDok").Value & "/"
.MoveNext
Loop
.Close

strGTI_Magazyn = Left(strGTI_Magazyn, Len(strGTI_Magazyn) - 1)
strGTI_DatyDok = Left(strGTI_DatyDok, Len(strGTI_DatyDok) - 1)
strGTI_NrDok = Left(strGTI_NrDok, Len(strGTI_NrDok) - 1)

'uzupełnienie danych porównania
With rcsBazaGTI
.Edit
.Fields("strGTI_Sprzedaż").Value = strGTI_Sprzedaż
.Fields("intGTI_IlośćDok").Value = intGTI_IlośćDok
.Fields("strGTI_Magazyn").Value = strGTI_Magazyn
.Fields("dteGTI_DataUmowy").Value = dteGTI_DataUmowy
.Fields("strGTI_DatyDok").Value = strGTI_DatyDok
.Fields("strGTI_NrDok").Value = strGTI_NrDok
.Update
End With

End If
End With
Set rcsSprzedażGTI = Nothing
End If

.MoveNext
Loop
.Close
End With
Set rcsBazaGTI = Nothing

Form_frmPanelKontrolny.prgPostęp.Value = 100
Form_frmPanelKontrolny.lblStaus.Caption = "Status: 100%"
DoCmd.RepaintObject acForm, Form_frmPanelKontrolny.Name

MsgBox "Gotowe!", vbInformation
Set dbsBieżąca = Nothing
End Sub
Bartosz Borczyk edytował(a) ten post dnia 21.10.09 o godzinie 23:38

konto usunięte

Temat: OPTYMALIZACJA

subselectem

http://articles.techrepublic.com.com/5100-10878_11-104...

taka rada:

myśl w kategorii zbiorów a nie rekordów - będzie szybciej ;)
Bartek Borczyk

Bartek Borczyk Operator liczb i
słów

Temat: OPTYMALIZACJA

Przemysław R.:
subselectem

http://articles.techrepublic.com.com/5100-10878_11-104...

taka rada:

myśl w kategorii zbiorów a nie rekordów - będzie szybciej ;)

Średnio czaje.
Bartek Borczyk

Bartek Borczyk Operator liczb i
słów

Temat: OPTYMALIZACJA

Wygląda na to, że najbardziej obciążającym zabiegiem jest porównywanie przez Like *. Po zmianie na równa się, procedura trwała niecałą minutę. I teraz mam zagwostkę.

O ile łatwiej byłoby jakby ci co raportują potrafili wpisywać poprawnie nr telefonu...

konto usunięte

Bartek Borczyk

Bartek Borczyk Operator liczb i
słów

Temat: OPTYMALIZACJA

Przemysław R.:
maska wprowadzania
http://office.microsoft.com/pl-pl/access/HA10096452104...

Hehe, wiem, wiem.

Problem w tym, że dane są wpisywane do systemu, który stoi na sql serverze. Do jego bebechów nie mam dostępu, nie odpowiadam też za kwestię poprawności wprowadzania danych, która krótko mówiąc jest zaniedbywana.

Generalnie powinienem zajmować się tylko analizą a nie łopatologicznym rzeźbieniem danych. To robię tak trochę maso-hobbystycznie :)
Bartek Borczyk

Bartek Borczyk Operator liczb i
słów

Temat: OPTYMALIZACJA

W starciu DAO vs ADO porównywalnie długo i niezadowalająco.

Następna dyskusja:

Szkolenie "Standaryzacja i ...




Wyślij zaproszenie do