Announcement

Collapse
No announcement yet.

Dataset und Performance

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Dataset und Performance

    Ich fange gerade mit Ado.net an und habe hierzu nach längerem Lesen mal ein einige Grundsatzfragen die Ihr mir vielleicht beantworten könnt.

    Ich habe ein großes Datenbankprojekt mit Vb 2005 und MySql mit ca. 100 Tabellen in denen auch schon mal 70000 Datensätze stehen können.

    Das ganze soll später in einer Mehrbenutzerumgebung laufen, bei denen 20 User gleichzeitig auf die Daten zugreifen.

    - macht es einen Unterschied, ob ich alle Tabellen in ein Dataset lade oder aber einzelne Datasets anlege?

    - den Connection String hinterlege ich in der Config Datei. Gibt es bessere Möglichkeiten?

    - gibt es andere Möglichkeiten als Datasets um Daten zu lesen/ändern/einfügen vor allem in Bezug auf die Performance?

  • #2
    Originally posted by daribla View Post
    Ich habe ein großes Datenbankprojekt mit Vb 2005 und MySql mit ca. 100 Tabellen in denen auch schon mal 70000 Datensätze stehen können.
    100 Tabellen ist nicht mehr klein, aber 70000 Datensätze ist nichts Besonderes.

    - macht es einen Unterschied, ob ich alle Tabellen in ein Dataset lade oder aber einzelne Datasets anlege?
    Nur für die Übersichtlichkeit. Ich finde es in der Regel praktischer, wenn ein DataSet einer Datenbank entspricht. Innerhalb eines DataSets können auch DataRelations (= ForeignKey) angelegt und berücksichtigt werden. Wichtiger ist, dass eine Tabelle einer DataTable entspricht.

    Wenn man per JOIN verschiedene Daten in eine DataTable zusammenfasst, hilft das u.U. der Anzeige; erschwert aber das Speichern von Änderungen erheblich. Da muss man Vor- und Nachteile genauestens abwägen.

    - den Connection String hinterlege ich in der Config Datei. Gibt es bessere Möglichkeiten?
    Nein, die ist genau dafür gedacht. Beachte aber die Verschlüsselung des Passworts, siehe z.B. [FAQ] DB-Password/Kennwort/Connection-String sicher speichern.

    - gibt es andere Möglichkeiten als Datasets um Daten zu lesen/ändern/einfügen vor allem in Bezug auf die Performance?
    Ja. ExecuteReader mit DbDataReader und ExecuteScalar sind schneller. Das Reader-Verfahren ist vor allem dann nützlich, wenn eine Teilmenge der Daten ausgewertet werden soll; ExecuteScalar wird für einen einzelnen Wert genutzt. Zum Speichern sind einzelne INSERT-, UPDATE-, DELETE-Befehle per DbCommand.ExecuteNonQuery schneller.

    Wenn eine ganze Menge angezeigt oder zur manuellen Bearbeitung zur Verfügung stehen soll, ist DataSet/DataTable mit DbDataAdapter.Fill/Update besser.

    Gruß Jürgen

    Comment


    • #3
      Danke ersmal für die schnelle Antwort.

      Da in dem Projekt später ständig lese-/schreibzugriffe erfolgen, ist es also dafür besser:

      - die komplette Datenbank als Datenquelle und somit als einziges Dataset der Anwendung zu erstellen

      - wenn Daten geändert werden (z.B Auftragspositionen), dann die Auftragspositionen zum angezeigten Auftrag nicht per Join (wegen umständlichen update) sondern evtl mit Filter anzeigen.

      Gibt es eine Möglichkeit, dem User, der einen Auftrag bearbeitet anzuzeigen, dass der Auftrag gerade von einem Anderen bearbeitet wird?

      Comment


      • #4
        Originally posted by daribla View Post
        Danke ersmal für die schnelle Antwort.
        Gern geschehen.

        Da in dem Projekt später ständig lese-/schreibzugriffe erfolgen, ist es also dafür besser:
        - die komplette Datenbank als Datenquelle und somit als einziges Dataset der Anwendung zu erstellen
        Was die Struktur betrifft: korrekt. Was die tatsächlichen Daten betrifft, hatte ich vergessen zu erwähnen, dass immer nur die tatsächlich benötigten Daten geladen werden sollen (ein Kunde, seine Aufträge usw.), aber nicht beim Programmstart alle Kunden, alle Aufträge. Lediglich Nachschlagetabellen (Auftragsarten u.ä.) stehen immer zur Verfügung. (Die Liste PLZ/Orte mit 100.000 Einträgen ist übrigens ein Grenzfall; für eine Adressenverwaltung mit vielen Kunden wäre das eine Nachschlagetabelle, für eine Auftragsverwaltung eher nicht.)

        - wenn Daten geändert werden (z.B Auftragspositionen), dann die Auftragspositionen zum angezeigten Auftrag nicht per Join (wegen umständlichen update) sondern evtl mit Filter anzeigen.
        Richtig. Als Filter gibt es übrigens DataView, und auch die BindingSource kann filtern.

        Gibt es eine Möglichkeit, dem User, der einen Auftrag bearbeitet anzuzeigen, dass der Auftrag gerade von einem Anderen bearbeitet wird?
        Jein. Soweit ich weiß, bietet MySql keine derartige Funktionalität. Bei MS-SQL wird von SqlDependency gesprochen: Die Datenbank teilt den Clients mit, dass sich etwas geändert hat. Bei anderen DBMS muss man das irgendwie selbst einbauen; beispielsweise so: Der "andere" trägt einen Vermerk in die DB ein "ich arbeite daran"; andere bekommen diesen Vermerk sofort zur Kenntnis; in regelmäßigen Abständen wird per Timer nachgefragt.

        Du siehst aber, dass dieses Verfahren sehr aufwändig ist. Üblicherweise wird eher beim Speichern geprüft, ob ein Datensatz inzwischen verändert wurde, und dann mit einer Meldung (oder sogar Exception) darauf reagiert.

        Gruß Jürgen

        Comment


        • #5
          Originally posted by daribla View Post
          Da in dem Projekt später ständig lese-/schreibzugriffe erfolgen, ist es also dafür besser:
          Das ist eine 1A möglichkeit sich jedliche Langsamheit ins Programm zu bauen.

          Es gibt ein paar Grundregeln die unabhängig von DBMS und verwendeter Klassenbibliothek sind:

          - Nur soviel Daten holen wie nötig
          - Abfragen/Inserts über prepared Statements oder noch besser (jedoch aufwändiger bei Multi-DB-Support) per Stored Procedures zu erledigen.
          - Alle Daten immer mit client-Curser abholen (geht bei MySQL eh nicht anders).

          Comment


          • #6
            Wenn ich die ganze Datanbank als Datenquelle angebe, wird daraus ja ein einziges Dataset generiert.

            - wie steuer ich denn dass nicht alle Daten beim Programmstart geladen werden bzw. nur die Nachschlagedaten komplett und die Auftragsdaten bei Bedarf


            - Client Cursor kenne ich von Recordsets aber bei .Net?

            - Über Stored Procedures hatte ich auch schon nachgedacht, wie spreche ich diese dann an und wie übergebe ich denen Parameter?

            Comment


            • #7
              Originally posted by daribla View Post
              Wenn ich die ganze Datanbank als Datenquelle angebe, wird daraus ja ein einziges Dataset generiert.

              - wie steuer ich denn dass nicht alle Daten beim Programmstart geladen werden bzw. nur die Nachschlagedaten komplett und die Auftragsdaten bei Bedarf
              Ein DbDataAdapter benutzt für Fill einen SELECT-Befehl und eine Zieltabelle. Es ist deine Aufgabe, diese zu gestalten: für Nachschlagetabellen "SELECT ID, Name FROM x" ohne WHERE, für die Auftragsdaten gezielt mit WHERE.

              - Über Stored Procedures hatte ich auch schon nachgedacht, wie spreche ich diese dann an und wie übergebe ich denen Parameter?
              Genauso wie Einzelbefehle mit DbCommand. Siehe auch [Artikelserie] Parameter von SQL Befehlen

              Gruß Jürgen

              PS. Kennst du als Einführung in ADO.NET das openbook Kap. 23 ff.?

              Comment


              • #8
                Mit dem Where ist mit klar, aber wenn ich meine Datenbank als Datenquelle angebe und das Dataset automatisch erstellt wurde, ist ja an jeder Tabelle schon ein Tableadapter (Fill()) vorhanden, der den Select auf alle Daten der Tabelle enthält.

                Ist es nicht so, dass wenn ich das Programm starte, dieses Dataset erstmal gefüllt ( d.h. die gesamte Datenbank abgefragt) wird uns somit schon eine Startverzögerung des Programms vorhanden ist?

                Wo liegt eigentlich der genaue Vorteil von Stored Procedures? Dies muss ich doch auch als Datenquelle angeben.

                Comment


                • #9
                  Nein... das DataSet wird nicht automatisch gefüllt. Wann welche Daten in ein DataSet geladen werden entscheidest Du.

                  Es werden 2 Komponenten erzeugt:
                  1. DataTables die der Struktur der Datenbank entsprechen (+ Rows usw.)
                  2. TableAdapter die für die Abfrage der Daten zuständig sind und die oben genannte DataTables zurückliefern

                  Comment


                  • #10
                    Originally posted by fanderlf View Post
                    Nein... das DataSet wird nicht automatisch gefüllt. Wann welche Daten in ein DataSet geladen werden entscheidest Du.
                    indem ich z.B. einen tableadapter mit einer where Klausel definiere, den ich später (auch mit parameterübergabe) einfach aufrufe?

                    Comment


                    • #11
                      indem ich z.B. einen tableadapter mit einer where Klausel definiere, den ich später (auch mit parameterübergabe) einfach aufrufe?
                      Indem du dem Tableadapter, den du vermutlich schon hast, eine weitere Fill Methode verpasst mit den entsprechenden Parametern und an der richtigen Stellen dan eben die passende Fill-Methode am Tableadapter aufrufst.

                      Comment


                      • #12
                        Originally posted by Ralf Jansen View Post
                        Indem du dem Tableadapter, den du vermutlich schon hast, eine weitere Fill Methode verpasst mit den entsprechenden Parametern und an der richtigen Stellen dan eben die passende Fill-Methode am Tableadapter aufrufst.
                        Genau, so meinte ich es. Denke ich habe es endgültig für mich geklärt.

                        Noch ein Schritt weiter:

                        - hätte ich gegenüber dieser Methode Vorteile, wenn ich Stored Procedures nutze?

                        Wenn ja, welche?

                        Comment


                        • #13
                          Für SELECT ist es egal. Allenfalls wenn du viele sehr verzwickte SELECTs hast, die sich nach internen Bedingungen Daten zusammensuchen müssen, könnten SPs Vorteile haben; normalerweise nicht.

                          Für Speichern-Befehle gilt Ähnliches: Wenn intern viele Bedingungen zu prüfen sind und Daten auf verschiedene Tabellen zu verteilen sind, haben SPs Vorteile. Wenn die Eingabefelder weitgehend den Tabellenfeldern entsprechen, sind direkte Befehle praktischer.

                          Gruß Jürgen

                          Comment


                          • #14
                            Originally posted by Ralf Jansen View Post
                            Indem du dem Tableadapter, den du vermutlich schon hast, eine weitere Fill Methode verpasst mit den entsprechenden Parametern und an der richtigen Stellen dan eben die passende Fill-Methode am Tableadapter aufrufst.
                            Noch mal eine Frage dazu.
                            Macht es einen Unterschied, ob ich das im Designer oder per Code mache?

                            Comment


                            • #15
                              Für den Arbeitsablauf nicht. Was du im Designer eingibst, schreibt die IDE in die jeweilige Designer.cs. Wenn du gleichen Code in andere Teile der Klasse schreibst, wird auch der gleiche Code übersetzt und ausgeführt.

                              Übersichtlicher ist es meistens, wenn du es selbst machst. Dann verstehst du auch, was abläuft, und nichts wird in einem Datenmonster wie dem TableAdapter versteckt.

                              Jürgen

                              Comment

                              Working...
                              X