Das Notes Forum

Domino 9 und frühere Versionen => ND6: Entwicklung => Thema gestartet von: bikerboy am 26.09.07 - 15:18:31

Titel: Walk the View
Beitrag von: bikerboy am 26.09.07 - 15:18:31
Hallo zusammen,

so böse Geschichte, muss redundante Daten aus einer DB löschen. Problem ist das die DB knapp 90.000 Dokumente umfasst. Sprenge mir jedes Array wenn ich versuche den passenden Schlüssel reinzuschreiben.

Also bin ich darauf zu kommen ein Wlak the View zu vollziehen, Problem ist ja wenn ich Dokumente rauslösche dass er durcheinander kommt, wenn ich zum Beispiel das Dokument lösche auf dem ich stehe.

Wie sieht es aus wenn ich die Spalte mit meinem Schlüssel kategorisiert anzeigen lassen und die 2 Spalte mit sortiere mit dem Wert der sehr wahrscheinlich der richtige ist ?

Hoffe die Beschreibung ist nicht all zu wirr.
Titel: Re: Walk the View
Beitrag von: m3 am 26.09.07 - 15:22:38
NotesDocumentCollection?
Titel: Re: Walk the View
Beitrag von: pete_bla am 26.09.07 - 15:45:32
Hi,

Die notesDocumentCollection hat ja den vorteil von
.removeall
Der ist bei vielen doch schneller als ein enzelnes löschen.

wenn Du einzelne löscht, und "die verschwinden Dir" dann lade doch einfach das nächste schon vor dem löschen
ungefähr so:
Code
while not doc is nothing
   set docnext = view.getnextdocument(doc)
   call doc.remove(true)
   set doc = docnext 
wend

Viel Erfolg, Pete(r)
Titel: Re: Walk the View
Beitrag von: bikerboy am 26.09.07 - 16:23:22
@m3 :

Ich sprenge doch bestimmt eine verdammte Grenze wenn ich 90.000 Dokumente einfüge , oder?

Aussderm lösche ich ja zwischendurch Dokumente, wenn ich auf nen leeren Slot springe, habe ich keinen Parameter mehr für getnextDocument. Und wenn ich mit getnthDocument arbeite springe ich am Ende aus der Kollektion, weil ja die Kollektion immer kleiner wird.

@pete_bla :

Die Idee ist gut, muss aber erst gucken inwiefern ich sie verwurste.
Titel: Re: Walk the View
Beitrag von: koehlerbv am 26.09.07 - 16:27:35
Zu Deinem eigentlichen Problem kann ich nichts sagen - ich kenne einfach nicht genügend Deiner Randbedingungen.

Aber: Eine DocumentCollection kannst Du nicht sprengen.
Und - ganz wichtig: Mit GetNthDocument arbeitet man nicht! Das geht bei 100 Dokumenten gut, aber schon ab 1.000 Dokumenten kannst Du jedem einzeln die Hand schütteln, und ab dem 10.000sten (oder so) wirst Du sterben, wenn Du bei jedem Dokument einen Kafee trinken gehst.
Arbeite mit GetNextDocument. Gleiches gilt auch für Collections.
(Hintergrund: Der Pointer zum Dokument muss jedes Mal neu von Anfang an gesetzt werden.)

Bernhard
Titel: Re: Walk the View
Beitrag von: flaite am 26.09.07 - 16:49:18
Benutz einfach die Idee von pete bla
Oder diese docLast Variante :-)
Code
set doc = vw.getFirstDocument
while not doc is nothing
   set docLast = doc
   set doc = view.getnextdocument(doc)
   ' code zum prüfen, ob docLast gelöscht werden kann, wenn ja dann löschen (nächste Zeile)
   call docLast.remove(true)
   
wend

Titel: Re: Walk the View
Beitrag von: koehlerbv am 26.09.07 - 17:08:06
Ich befürchte, das "docLast" oder "docNext" lösen nicht Roberts Problem: Es sollen ja wohl Dubletten gelöscht werden. Und die können sich sonstwo in der View verstecken. Diese muss also dauernd reindexiert werden, und wo der Schuss nun gerade ein Loch hinterlassen hat, kann man ja nur aufwändig feststellen und merken.

Je mehr Dokumente während des Laufs nun gekillt werden, desto performancefressender würde auch bei einem inaktiven Index-AutoUpdate die nun erforderliche Prüfung, ob das gefundene (zu löschende oder zu bearbeitende Dokument) nun eine Leiche ist oder noch zappelt.

Wie schon oben gesagt: Hier kann man nur Empfehlungen geben, wenn man mehr über die Gesamtsituation und die Anforderungen weiss.

Bernhard
Titel: Re: Walk the View
Beitrag von: Thomas Schulte am 26.09.07 - 17:14:46
Alles in Listen reinschreiben und dann mit diesen arbeiten. Es könnte allerdings sein das du mit der Anzahl von Dokumenten zuverlässig einen RSOD erzeugst.
Titel: Re: Walk the View
Beitrag von: pete_bla am 26.09.07 - 17:23:44
Hi,

wenns nun wirklich eine "einmalige Killaktion" sein sollte,
würde ich mal auf das klassische
Code
collection = db.Search(Formel,Nothing,0) 
verweisen,
da ja eine "Formel" dahinterliegt...
und dann
Code
collection.removeall()

Ich finde für sowas ist das db.Search() optimal!

Gruss, Pete(r)
Titel: Re: Walk the View
Beitrag von: m3 am 26.09.07 - 20:15:22
Also bei mir hat er gerade 7 Sekunden gebraucht, um mit getNextDocument eine Collection mit 31.499 Dokumenten zu durchlaufen.  :)
Titel: Re: Walk the View
Beitrag von: koehlerbv am 26.09.07 - 20:24:19
Wenn Du schon dabei bist: Und mit GetNthDocument?

Bernhard
Titel: Re: Walk the View
Beitrag von: m3 am 26.09.07 - 21:17:47
31.499 Dokumente in 367 Sekunden durchlaufen.
Titel: Re: Walk the View
Beitrag von: bikerboy am 27.09.07 - 13:24:10
So , ich bedanke mich schon mal, hatte gestern leider die zeit nicht mehr um hier vorbei zu schauen.

Haber mit GetNextDocument gearbeitet , hier einmal der KernCode :

Code
	Set viewDoc = view.GetFirstDocument
	searchKey = Cstr(viewDoc.GetItemValue("pumpSearchKey")(0))
	i = 0
	While Not  viewDoc Is Nothing
		
		Set redundantDoc = view.GetNextDocument(viewDoc)
		While ready = False
			
			If Not redundantDoc Is Nothing Then
				If Cstr(redundantDoc.GetItemValue("pumpSearchKey")(0)) = searchKey Then			
					Call redundantDoc.Remove(True)
					Set redundantDoc = view.GetNextDocument(viewDoc)
				Else
					ready = True
				End If	
			End If
			i = i +1
			Print "Datensatz : " + Cstr(i) + " bearbeitet!"
		Wend
		
		Set viewDoc = view.GetNextDocument(viewDoc)		
		searchKey = Cstr(viewDoc.GetItemValue("pumpSearchKey")(0))
		ready = False
		i = i +1
		Print "Datensatz : " + Cstr(i) + " bearbeitet!"
	Wend		
	

Am Anfang arbeitet er auch richtig performant und dann so ab 13.500 Dokumenten wird es ziemlich langsam und am Ende hängt er sich ganz weg.

Kann mir einer sagen was ich besser machen kann.

Ach bevor ich es vergesse, durch eine View habe ich die Dokumente so sortiert, dass das erste Dokument mit dem Schlüssel auch gleich das richtige ist.
Titel: Re: Walk the View
Beitrag von: koehlerbv am 27.09.07 - 13:29:23
Hast Du die AutoUpdate-Property auf False gesetzt?

Was man häufig unterschätzt: Print-Statements fressen mehr Performance, als man denkt (das ist aber im Gegensatz zum hier vermutlich überforderten Indexer nicht das Killerkriterium).

Bernhard
Titel: Re: Walk the View
Beitrag von: bikerboy am 27.09.07 - 13:31:04
Du meinst von der View ? Keine Ahnung muss ich gleich mal schauen.


Die Prints sollen drin bleiben, von wegen, damit man sieht dass er noch was tut.
Titel: Re: Walk the View
Beitrag von: Driri am 27.09.07 - 13:32:27
Was ist denn "ready" ?

Wofür ist die 2. While-Schleife gut (While ready=False) ?

Du zählst i innerhalb von 2 Schleifen hoch. Das führt zu falschen Ergebnissen.
Titel: Re: Walk the View
Beitrag von: bikerboy am 27.09.07 - 13:37:34
ready ist ein Bool-Wert. Soll halt die abarbeitung unterbrechen.


i ist ja nur für mich als optisches Zeichen, dass da was passiert, selbst wenn was falsches drin steht ist "Bumms", weil er nix steuert. Aber ich glaube schon dass das richtige drin steht, zumindest hat mein Papier-PC das gesagt.
Titel: Re: Walk the View
Beitrag von: rbo am 27.09.07 - 13:48:33
Hi,

ich persönlich würde es auch mit Listen machen...
Mir ist gerade ein wenig langweilig, versuch doch mal diesen Code (nicht getestet)
Code
	Dim searchkeys List As Boolean
	
	
	While Not viewDoc Is Nothing
		
		If Iselement(searchKeys(viewDoc.GetItemValue("pumpSearchKey")(0))) Then
			Call viewDoc.remove
		Else
			searchKeys(viewDoc.GetItemValue("pumpSearchKey")(0)) = True
		End If
		
		Set viewDoc = view.getNextDocument(viewDoc)
	Wend

Müsste wesentlich performanter sein als dein jetziger Code...
Sollte dir die Liste wirklich um die Ohren fliegen musst du ein anderes Medium zum zwischenspeichern gefundener Elemente finden (zb. Tempdoc)

Gruss René

EDIT:
So gehts natürlich nicht ganz, du mussts den Code ein wenig modifizieren weil

Set viewDoc = view.getNextDocument(viewDoc)

mit dem gelöschten Dok nicht klappt, Lösung steht allerdings weiter oben, dann sollte es passen...
   
Titel: Re: Walk the View
Beitrag von: bikerboy am 27.09.07 - 13:52:06
ja mit listen habe ich am anfang auch gearbeitet, nur ein Array, dass 90.000 * 39 byte fast kann mein system nicht. da laufen mir der ein oder andere speicher über.
Titel: Re: Walk the View
Beitrag von: flaite am 27.09.07 - 13:56:06
Ist das nicht so einfacher?
Code
 
Dim lastValue as String

lastValue = "DAT_KANNES_ÜBERHAUPT_NICHT_GEBEN. ES_HARTO IMPROBABLE QUE una Casilla tenga un contenido así"
set doc = vw.getFirstDocument
while not doc is nothing
   
   set docLast = doc
   set doc = view.getnextdocument(doc)
   if docLast.pumpsearchkey(0) = lastValue then 
          lastValue = docLast.pumpsearchkey(0)
          call docLast.remove(true)
   else
        lastValue= docLast.pumpsearchkey(0)
   end if
wend
Titel: Re: Walk the View
Beitrag von: bikerboy am 27.09.07 - 13:58:12
so nochmal neue Erkenntnisse , habe ihn mal absichtlich am Ende auf nen Fehler laufen lassen, und den habe ich schon nach 15 min erreicht. Habe dann mein ergebnis kontroliert und siehe da , er hat korrekt gearbeitet. Notes hat danach ein Problem die Ansicht aufzubauen.

@Diri du hattest recht hatte am Ende eine Zahl die etwas grösser ist als die gesamte Anzahl in der DB, aber naja so sieht es halt aus als würde er ganz viel tun und das in ganz kurzer Zeit :P .
Titel: Re: Walk the View
Beitrag von: Driri am 27.09.07 - 13:59:11
Jopp, darauf wollte ich mit der Frage nach der 2. While-Schleife eigentlich hinaus. Die ist eigentlich über und in dem Moment, wo innerhalb der 2. While-Schleife ready = true gesetzt wird, ist das Ergebnis von i IMO auch falsch, weil i zweimal hochgezählt wird.

Hupps, zu langsam. Mein Posting bezieht sich auf AJs  ;)
Titel: Re: Walk the View
Beitrag von: bikerboy am 27.09.07 - 14:01:17
@Axel Janssen

Ich weiss nicht wie das mit der Zeile

Code
Set lastdoc = doc

aussieht wird dann nicht einfach nur ein Zeige auf Doc gesetzt? Dann könnte man sich den Vergleich sparen, weil es das selbe Doc ist
Titel: Re: Walk the View
Beitrag von: DerAndre am 27.09.07 - 14:10:27
Das ist kein Vergleich sondern eine Zuweisung.

Genau das ist es ja. Danach wird das nächste Doc genommen und Du kannst es u.U. löschen ohne auf die Nase zu fallen. Weiel Du dann LastDoc löscht und nicht Dein Laufzeigerdoc.
Titel: Re: Walk the View
Beitrag von: bikerboy am 27.09.07 - 17:19:05
So ist gelöst, mache nun folgendes. Erst markiere ich alle überflüssigen DOCs mit nem neuen Feld und dann mache ich ne Kollektion auf in die alle diese Docs reinkommen. Dann ein schneidiges docColl.remove(true) und fertig ist die Laube, nur notes kackt dann ab , weil er wohl nicht verkraftet dass aus einer ansicht über 76.000 dokumente verschwinden.

Aber irgendwas ist ja immer, ich bedanke mich für die gute Zusammenarbeit.
Titel: Re: Walk the View
Beitrag von: koehlerbv am 27.09.07 - 17:38:55
... nur notes kackt dann ab , weil er wohl nicht verkraftet dass aus einer ansicht über 76.000 dokumente verschwinden.

Das Notes deswegen Exkremente absondert, ist eigentlich alles andere als normal (habe ich noch nie erlebt). Wenn Du den Act lokal machst, ist es völlig normal, dass es eine Weile dauert, bis der / die Ansichtsindizes wieder aufgebaut sind, dito auf dem Domino, wenn die Aktion dort lief. Aber wenn der Client deswegen crasht, ist es sehr merkwürdig.

Bernhard
Titel: Re: Walk the View
Beitrag von: bikerboy am 28.09.07 - 08:44:17
naja ich bekomme keine RedBox oder so, aber das er länger als ne Stunde braucht ist schon unnormal. Also ich habe dann nach einer Stunde abgebrochen , weil es mir zu viel wurde.
Titel: Re: Walk the View
Beitrag von: DerAndre am 28.09.07 - 08:49:03
Bist Du sicher nicht in einer Endlosschleife gelandet zu sein?
Titel: Re: Walk the View
Beitrag von: bikerboy am 28.09.07 - 08:58:20
Ja sehr sogar, ich hatte mir nen BreakPoint auf EndSub gesetzt und da bin ich auch angekommen und danach hat er sich dann auf etwas gestürzt was ihn fertig macht. Also Fehler in meinem Code mal zum Glück ausgeschlossen.
Titel: Re: Walk the View
Beitrag von: pete_bla am 28.09.07 - 14:12:06
Hi,

wenn dein Client wohl beim refreshen der Ansicht "ab..." gäbe es noch einen Vorschlag:

1. Wenn du keine manuelle Dokumentenauswahl machst und die Aktion sowieso intern auf eine Ansicht springt, dann starte doch das als Agent von "Ausserhalb" ohne die Datenbank "aufzumachen":
Nur DB-Kachel auf dem Worksapace anklicken,
dann über "Aktionen" den Agent starten.

Dies bringt bezüglich eines View-Refreshs oft einiges an Performance, besonders wenn Du ansonsten sogar in der Ansicht stehst.

2. würde ich noch die "Print-Commands" einschränken, bzw. in ein Log oder in ein File schreiben,
da eben ein Print in die Statuszeile bei tausenden Ausgaben das auch sehr verlangsamt.
Du kannst ja immernoch jedes 100ste oder 1000ste Print auf die Statuszeile senden, damit du weisst dass was läuft.

Gruss , Pete(r)
Titel: Re: Walk the View
Beitrag von: bikerboy am 28.09.07 - 17:00:09
@pete_bla


Super tip! Rennt wie Hölle


allen ein Schönes WE