0

Geschwindigkeitsoptimierung: Große Menge an Datensätzen schneller verknüpfen.

Ich nutze die Desktop App von Ninox am Mac um Datensätze anhand des EAN Barcodes Produkten in unserer Tabelle zuzuordnen. In der Datenbank gibt es 188 Produkte und halbjährlich müssen aktuell circa 200.000 Einträge aus der Tabelle 'Curve Sales' zugewiesen werden. Da die Tabelle jedesmal jeden Eintrag prüft ob er bereits zugewiesen wurde oder nicht, dauert es jedes Mal länger und zum Teil mehrere Tage, manchmal wird auch der Vorgang abgebrochen. Gibt es eine Möglichkeit den Vorgang zu beschleunigen? AI Tools wie ChatGPT und Grok habe ich getestet kommen aber zu keinem verwertbarem Ergebnis. Hier der Code:

let produktListe := (select Produkte);
let counter := 0;
for i in select 'Curve Sales' where Produkte = null do
    let myProdukt := first(produktListe['UPC / EAN Barcode' = i.Barcode]);
    if myProdukt != null then
        i.(Produkte := myProdukt);
        i.(Kontaktgruppe := myProdukt.Artist);
        counter := counter + 1
    end
end;
alert("Es wurden " + text(counter) + " Datensätze aktualisiert.")

 

Was ein zusätzliches Problem sein könnte, warum der Vorgang so lange dauert:

Jeder Eintrag wird außer der Verknüpfung zu 'Produkte' auch einer 'Kontaktgruppe' zugewiesen. In einem zweiten Schritt müssen wir die Einträge auch entsprechend einem Prozentverhältnis welches in 'Produkte' festgelegt wurde 'Quittungen' zuweisen um daraus Abrechnungen an unsere Artists / 'Kontaktgruppen' zu erstellen. 'Quittungen' können erst erstellt werden sobald ein Mindestbetrag erreicht ist, daher hatte ich folgende Felder als Funktionsfelder in den 'Curve Sales' festgelegt, was vermutlich ungünstig ist:

Download Deal (Formel: Produkte.'Deal Download')
Download Stück (Formel: Produkte.'Stückpreis Artist Download')
Download Anteil (Formel: Produkte.'Anteil Artist Download')
Streaming Deal (Formel: Produkte.'Deal Streaming')
Streaming Stück (Formel: Produkte.'Stückpreis Artist Streaming')
Streaming Anteil (Formel: Produkte.'Anteil Artist Streaming')

NET_ARTIST (fkt.)

if text(Configuration) != "Download" and text('Streaming Deal') = "Anteil" then
    'Net Payable' * 'Streaming Anteil' / 100
else
    if text(Configuration) != "Download" and text('Streaming Deal') = "Stückpreis" then
        'Streaming Stück' * Units
    else
        if text(Configuration) = "Download" and text('Download Deal') = "Anteil" then
            'Net Payable' * 'Download Anteil' / 100
        else
            if text(Configuration) = "Download" and text('Download Deal') = "Stückpreis" then
                'Download Stück' * Units
            end
        end
    end
end

NET_LABEL (fkt.)

'Net Payable' - NET_ARTIST

Anfangs dachte ich es wäre eine gute Idee mit Funktionsfeldern zu Arbeiten, da es unterschiedliche Vertragsarten (Stück oder Anteil) gibt und sich diese auch in der Zukunft ändern können. Bei großen Datenmengen, ist es allerdings zu großer Aufwand. 

Ich bräuchte unbedingt Hilfe das Datenmodell so umzubauen, dass alles funktioniert und die Rechenleistung minimiert wird. Vielen Dank!

9 replies

null
    • Reinhard
    • 4 days ago
    • Reported - view

    Mein erster Ansatz zur Optimierung wäre nun, zuerst die Funktionsfelder in 'Curve Sales' durch feststehende, einmal berechnete Text und Zahlenfelder zu ersetzen. Ist das sinnvoll um die Prozesse zu beschleunigen?

    • Fred
    • 3 days ago
    • Reported - view

    Can you post a DB with sample data?

    So every 6 months, you import 200K records in a table that you then need to link each record? or you import new records and only those records need to be linked?

      • Reinhard
      • 3 days ago
      • Reported - view

       jeder neue eintrag aus curve sales, der noch keinem 'Produkte' zugewiesen wurde, soll einem zugewiesen werden. Anhand des 'Produkte' werden funktionsfelder in jedem record berechnet, da jedes Produkt einen eigenen Vertrag hat, und der gesamtbetrag eines curve eintrages normalerweise Prozentual gesplittet werden muss.

      Samples kann ich nicht öffentlich posten, hier bräuchte ich einen direkten Kontakt oder SCreenshare. Die DB ist außerdem sehr groß ich müsste hierfür erst einiges löschen, umbauen etc. wenn es wirklich hilft kann ich das machen. 

    • Fred
    • 3 days ago
    • Reported - view

    How many records does this code return?

    select 'Curve Sales' where Produkte = null
    

    Which table is this button located?

      • Reinhard
      • 2 days ago
      • Reported - view

       da ich gerade (seit 1 Tag) einen Befehl ausführe kann ich nichts berechnen. Ich hatte aber nachgesehen, es sind pro Monat etwa 10k einträge, also insgesamt circa 70k. Produkte habe ich 188 also überschaubar. ChatGPT meint es kann helfen alle Einträge erst nach Barcodes zu gruppieren, ehe ich sie den Produkten zuweise, eben teste ich diese Formel, beschränkt auf circa 10k EInträge Monat Juli 2025:

      let recs := select 'Curve Sales'
          where Produkte = null and 'Booking Period' = "2025-07";
      
      let produktListe := select Produkte;
      let counter := 0;
      
      let barcodes := unique(recs.Barcode);
      
      for b in barcodes do
      
          let p := first(produktListe['UPC / EAN Barcode' = b]);
      
          if p then
      
              let myRecs := recs[Barcode = b];
      
              for i in myRecs do
                  i.(Produkte := p; Kontaktgruppe := p.Artist);
                  counter := counter + 1
              end
      
          end
      
      end;
      
      alert("Testlauf: " + text(counter) + " Datensätze aktualisiert.")
    • Fred
    • 7 hrs ago
    • Reported - view
     said:
    BUt I, there are about 10k entries per month, so a total of about 70k.

    Is there a way you can change your work flow so that you work with smaller sets of data?

    How are you entering data?

      • Reinhard
      • 6 hrs ago
      • Reported - view

       bis jetzt habe ich alle funktionsfelder durch statische text felder ersetzt. Es war kein riesiger Unterschied feststellbar. Dann habe ich in kleinere Sets (Monatsweise) gestaffelt. Die Verlinkung zu Produkt und Kontaktgruppe funktioniert damit annehmbar in ein paar Stunden pro Abrechnungsmonat. 

      Problematisch ist noch die Anteilmäßige Berechnung pro Datensatz. Das hatte bis 10k annehmbar funktioniert ein Monat mit 16 k Einträgen machte Probleme, nun ist die Formel für die Feldberechnung auf 8k limitiert. ich warte gerade seit ein paar Stunden auf das Ergebnis. 

      Importiert werden die Daten monatsweise mittels .csv Tabellen. Da jeder Eintrag abhängig von seinem Produkt / Barcode eigene Verträge mit individuellem Split nutzt, kann ich maximal nur nach Produkt gruppieren. 
       

      let periode := 'Booking Period Auswahl (YYYY-MM)';
      
      let recs :=
          if periode != "" then
              select 'Curve Sales'
                  where Produkte != null
                  and NET_ARTIST_FIX = null
                  and Booking_Period_FIX = periode
          else
              select 'Curve Sales'
                  where Produkte != null
                  and NET_ARTIST_FIX = null
          end;
      
      let batch := slice(recs, 0, 8000);
      let counter := 0;
      
      for i in batch do
          let p := i.Produkte;
          let netPayable := i.'Net Payable';
          let units := i.Units;
          let isDownload := i.Configuration = "Download";
      
          let dealDownload := p.'Deal Download';
          let dealStreaming := p.'Deal Streaming';
          let anteilDownload := p.'Anteil Artist Download';
          let anteilStreaming := p.'Anteil Artist Streaming';
          let priceDownload := p.'Stückpreis Artist Download';
          let priceStreaming := p.'Stückpreis Artist Streaming';
      
          let netArtist :=
              if isDownload then
                  if dealDownload = 1 then
                      netPayable * anteilDownload / 100
                  else
                      priceDownload * units
                  end
              else
                  if dealStreaming = 1 then
                      netPayable * anteilStreaming / 100
                  else
                      priceStreaming * units
                  end
              end;
      
          i.(
              Download_Deal := text(dealDownload);
              Download_Stueck := priceDownload;
              Download_Anteil := anteilDownload;
              Streaming_Deal := text(dealStreaming);
              Streaming_Stueck := priceStreaming;
              Streaming_Anteil := anteilStreaming;
              NET_ARTIST_FIX := netArtist;
              NET_LABEL_FIX := netPayable - netArtist
          );
      
          counter := counter + 1
      end;
      
      alert(
          if periode != "" then
              "Batch fertig (" + periode + "): " + text(counter) + " Datensätze"
          else
              "Batch fertig (alle): " + text(counter) + " Datensätze"
          end
      )
      
      • Reinhard
      • 6 hrs ago
      • Reported - view

       da es sehr viele Einträge pro Monat sind 20k die dann 180 Produkten zugewiesen werden sollen, wäre die technische Frage an Ninox ob es sinnvoll wäre erst alle Einträge nach Produkten zu gruppieren und anschließend einmal die Daten für die Deals / Anteile zu holen und zu berechnen?

      Würde das das System entlasten?

      • Fred
      • 3 hrs ago
      • Reported - view

       For such technical questions like this you may want to ask Ninox directly.

Content aside

  • 3 hrs agoLast active
  • 9Replies
  • 42Views
  • 2 Following