[C#] performance probleem updaten DataRow

Pagina: 1
Acties:
  • 415 views sinds 30-01-2008
  • Reageer

  • Rainmaker1987
  • Registratie: Juni 2005
  • Laatst online: 08-12-2024
Voor een updateproces moet ik een aantal tabellen tegen elkaar vergelijken. Na stap 3 moeten de records die ik heb verwerkt niet meer worden gebruikt. Om de gegevens netjes te bewaren zet ik een status gedaan op 1.

Bij het updaten van dit veld dropt de performance bij 1 van de tabellen.

C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
            //Klaarzetten gegevens
            DataRow[] update = dataSet11.Tables["update"].Select();
            progressBar6.Maximum = update.Count();
            int x = 0;
            int hetzelfde = 0;

            //ALLE UPDATE_ROWS vergelijken met systeem
            foreach (DataRow update_row in update)
            {
                x++;
                progressBar6.Value = x;

                //relatie_gegevens selecteren
                string select = "id_woningstichting = '" + update_row[5] + "'";
                DataRow[] gegevens = dataSet11.Tables["relatie_gegevens"].Select(select);
                if (gegevens.Count() > 0)
                {
                    DataRow gegevens_row = gegevens[0];
                    select = "id_relatie = '" + Convert.ToString(gegevens_row[0]) + "'";
                    DataRow[] relatie = dataSet11.Tables["relatie"].Select(select);
                    string id_huis = Convert.ToString(relatie[0][1]);
                    select = "id = '" + id_huis + "'";
                    DataRow[] woning = dataSet11.Tables["woning"].Select(select);
                    id_huis = Convert.ToString(woning[0][1]);
                    if (Convert.ToString(update_row[1]) == Convert.ToString(id_huis))
                    {
                       // Console.WriteLine("Hetzelfde huis: " + id_huis + " " + update_row[1]);
                        //update_row["gedaan"] = 1;
                       // gegevens[0]["gedaan"] = "1";
                        gegevens_row.Delete();
                        update_row.Delete();
                        hetzelfde++;
                    }
                }
            }


Bovenstaande code heb ik ook geprobeerd de status te veranderen ipv de DataRows te verwijderen. Ook heb ik het geprobeerd via gegevens[0]["gedaan"] = 1; Zowel als string en als cijfer. Het probleem zit hem in de gegevens_row en niet bij de update_row. Het verschil bedraagt van een verwerking van een paar tellen tot vele minuten. Er moet dus ergens een fout zitten, maar ik zie niet waar er een performance verbetering kan worden gevonden.

Iemand ideeen voor een betere performance bij dataset updaten?

  • whoami
  • Registratie: December 2000
  • Laatst online: 22:26
EnforceConstraints afzetten voor je aan de verwerking begint , en terug aanzetten als je verwerking gedaan is, kan in bepaalde gevallen helpen.
(Als je constraints hebt, en bewerkingen doen op data waarop constraints liggen bv).

https://fgheysels.github.io/


  • Rainmaker1987
  • Registratie: Juni 2005
  • Laatst online: 08-12-2024
Even een flinke kick. EnforceConstraints uitgezet maar ook dit mag niet helpen. De verschillen zijn nog steeds gigantisch. Ik heb ze even getimed:

relatienrgedaantijd
poging 1neenee2,9 seconden
poging 2janee20,3 seconden
poging 3jaja32:54 minuten

(relatienr houdt in dat met Console.WriteLine de betreffende relatienr's worden geprint en gedaan houdt in dat bij gegevens_row de rij gedaan op 1 wordt gezet.)

Het verschil blijft dus erg groot. Ik heb ook geprobeerd om de relatienummers opnieuw te gebruiken en vervolgens met table.Rows.Find(relatienr) de betreffende rij op te zoeken en te updaten. Dit zorgt voor dezelfde vertraging.

Heeft iemand nog een idee waar het aan zou kunnen liggen? (en vooral hoe ik het zou kunnen oplossen)

  • Niemand_Anders
  • Registratie: Juli 2006
  • Laatst online: 09-07-2024

Niemand_Anders

Dat was ik niet..

Je kunt de update niet direct op de database zelf uitvoeren. Je importeert de nieuwe gegevens in een (tijdelijke) tabel waarna je via sql queries record gaat vergelijken, updaten, of verwijderen.

Als je gebruik maakt van een MS SQL Server dan kun je voor de import naar de (tijdelijke) tabel SqlBulkCopy.

If it isn't broken, fix it until it is..


  • Rainmaker1987
  • Registratie: Juni 2005
  • Laatst online: 08-12-2024
Dat begrijp ik ook. Ik download de gegevens en zet deze in een dataset zoals ook te zien is. Datasets kan je wel direct updaten. Het probleem zit hem echter in het updaten van 1 waarde in de tabel relatie_eigenschappen welke de doorlooptijd in een keer flink verhoogd zonder reden. Het werkt dus wel maar op een onlogische wijze wordt de doorlooptijd veel langer. En mijn vraag is waardoor dat zou kunnen komen.

  • HawVer
  • Registratie: Februari 2002
  • Laatst online: 17-11 22:54
Het is om te beginnen bad practice om dingen in een dataset te wijzigen terwijl je dat dataset ook gebruikt in je loop. Probeer goed je loop in kaart te bregen, daar maakt je makkelijk fouten.

Een mogelijke oplossing is het gebruik van stored procedures, die geven je een betere controlle over wat er op de achtergrond wordt uitgevoerd.

http://hawvie.deviantart.com/


  • Rainmaker1987
  • Registratie: Juni 2005
  • Laatst online: 08-12-2024
Even een kick.

Een tijd geleden heb ik het probleem weten op te lossen door de gegevens eerst even naar een text bestandje weg te schrijven en vervolgens het een stuk later weer uit te lezen om de gegevens te wijzigen.

Door wijzigingen in aangeleverde bestanden heb ik het één en ander moeten wijzigen. Het probleem van de tijd is daarmee teruggekomen. De volgende code heb ik in een aparte functie neergezet om de gegevens te laten wijzigen:

C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
        public void afvoeren_doorvoeren()
        {
            DataTable eigenschappen = dataSet11.Tables["relatie_eigenschappen"];
            dataSet11.EnforceConstraints = false;
            StreamReader SR = new StreamReader("afvoeren.txt");
            string line = "";
            line = SR.ReadLine();
            //WIJZIGINGEN DOORSCHRIJVEN
            while (line != null)
            {
                String[] lines = line.Split(';');
                string select = "id = '" + lines[0] + "'";
                DataRow[] gegevens_row = eigenschappen.Select(select);
                // foreach (DataRow gegevens_row1 in gegevens_row)
                // {
                //   Console.WriteLine(lines[2]);
                //    gegevens_row1[2] = lines[2];
                // }
                 gegevens_row[0][2] = lines[2];

                // gegevens_row[0].SetValue(lines[2], 2);

               // gegevens_row[0].BeginEdit();
               // gegevens_row[0][2] = lines[2];
               // gegevens_row[0].EndEdit();
                line = SR.ReadLine();

            }


Zoals te zien is heb ik verscheidene methodes gebruikt. Echter alles zorgt ervoor dat mijn doorlooptijd van dit ene onderdeel omhoog schiet van minder dan 1 minuut naar ongeveer 30 minuten. En dat terwijl ik een stuk verderop wel wijzigingen door kan voeren zonder tijdsverlies. Het update process heb ik nu dus losgekoppeld van het vergelijkingsprocess zoals HawVer voorstelde, het direct updaten in de MySQL database is echter geen optie aangezien deze op een server staat waar geen directe verbinding mee kan worden gemaakt (gegevens worden via php als XML bestanden uitgelezen).

Heeft iemand een voorbeeld hoe dit wel zou moeten?

  • Niek.NET
  • Registratie: Oktober 2005
  • Laatst online: 18-11 13:04
Is de schema van je te importeren data gelijk?

Zo ja, lees huidige data in een DataSet en lees de nieuwe data in een DataSet en gebruik de Merge methode om beide datasets samen te voegen.

Zie: http://www.devasp.net/net/articles/display/706.html


Mocht je schema niet overeenkomen zou ik overwegen de xml data te converteren alvorens deze in te laden in je dataset waarna je deze alsnog kunt mergen.

  • Rainmaker1987
  • Registratie: Juni 2005
  • Laatst online: 08-12-2024
De bestanden die worden aangeleverd worden voornamelijk gebruikt om de huidige gegevens te updaten. Dwz er komen afmeldingsdata bij of verhuizingen. Met het doorvoeren van de nieuwe gegevens heb ik geen enkel probleem dat gaat binnen enkele seconden. Het updaten geeft echter wel problemen.

Mergen is dus geen optie aangezien de gegevens overgeschreven moeten worden.
Pagina: 1