Datenbank Designe Performance??



  • Die zweite ist scheisse 😉

    Da sich alles immer noch in einer Tabelle abspielt glaube ich auch nicht, dass das eine groß schneller als das andere sein wird (kenn mich da aber auch nicht so aus, nur denke ich halt nicht, dass sich sowas wirklich bemerkbar macht).



  • Lol, Kids 🙂
    Lass dich nicht verwirren, die 2. ist recht oft sehr sehr gut.

    Das Beispiel ist IMO allerdings "falsch", die 1. Variante müsste so aussehen:

    Id | Type| Value
    0   A      1
    0   B      2
    0   C      3 
    1   A      1 
    1   B      2
    1   C      3
    

    Wenn du eine Lösung brauchst die eine variable Anzahl bzw. variable Typen von Attributen zu einem Eintrag in der DB ermöglicht, dann musst du wohl Variante 1 nehmen. Abfragen wo du mehrere Attribute ermitteln musst werden dann aber garantiert langsamer sein als mit Variante 2.

    Was PostgresSQL hier genau kann oder nicht kann weiss ich nicht, aber zumindest auf MSSQL kann man solche Abfragen durch sog. Indexed Views beschleunigen.



  • hustbaer schrieb:

    Lass dich nicht verwirren, die 2. ist recht oft sehr sehr gut.

    nochmal darueber nachgedacht muss ich dir recht geben, allerdings geht es aus der Fragestellung nicht hervor, was gewollt ist..

    in der Regel geht man davon aus, was einen Datensatz darstellt
    Wenn ein Datensatz nur ein Wertepaar sein soll, wie es zum Beispiel in Tabellen gemacht wird, die Benutzereinstellungen speichern, nimm Variante 1. Da ist es kein Problem, weitere Typen hinzuzufuegen oder zu entfernen.
    Hier wird auch in der Regel nur der Wert zu einem Typen aus der Datenbank geholt und selten mehrere auf einmal.

    Wenn allerdings ein Datensatz aus mehreren Feldern besteht, diese aber in jedem Datensatz gleich sind, nimm Variante 2. Adressen waeren hier ein gutes Beispiel. Da ist es unwahrscheinlich, dass neue Felder dazukommen.



  • ich dachte mir schon das B schneller ist als A. Ein zwischending gibts wohl nich... nun muss ich abwägen. Was wäre denn besser, wenn ich die daten in mehre Datenbanken (meinentwegen eine pro tag) aufteile und die danten nacheinander selectiere, oder alles in eine datenbank haue und nur die selectiere. Mit selectieren meine ich ne Abfrage machen;)



  • IMO auf keinen Fall mehrere Datenbanken.

    Wenn dann mehrere Tables, oder noch besser: einen "partitioned table".
    Oder gleich einfach bloss einen Table + passende Indexe.

    Was wie performant ist, und was wieviel Resourcen (z.B. Speicher auf der Disk) braucht, kommt sehr stark auf die Datenbank an.
    Einige Datenbanken können z.B. Datensätze so speichern dass NULL Werte keinen Platz brauchen, andere können es nicht. Einige Datenbanken können "clustered tables" machen, andere nicht. Einige können "coverind indexes" verwenden, anderen nicht. Etcpp.

    Die Frage ist aber wirklich was du da abspeichern willst.
    Wenn es nicht Attribute einer einzigen "Entity" sind die du da zusammenfassen willst, dann lass es.

    Gib uns mal etwas mehr Informationen darüber was du da speichern willst, also was das für Daten sind. Und bitte in mehr als 3 Wörtern, sonst hilft das wenig 😉



  • Also ich hab mir nun folgendes design überlegt.
    Vorerst weg, ich möchste daten loggen. Die Daten können theoretisch von unterschiedlichen Typen sein, wobei ich diese immer in einem "real" 4 Byte abspeichere egal ob int, bool, oder float.

    -- Values ----
    ValueName (char 50), Type (int), ValueID (Key)
    
    -- Logging Data ---
    TimeStamp (UTC) , TimeID (key, counter), ValueType (int), Value (real)
    

    über den ValueType in LoggingData wird der DatenTypeName aus Values bezogen.

    Ich verwende PostgreSQL was hat es mit clusteredTable auf sich? Wird da die Tabelle aufgeteilt, und kann so schneller gescant werden?



  • Noch was.. wenn ich da nun mehrer millisionen datensätze habe und abfragen machen mit "WHERE" etc. gibts da performacne vorteile wenn ich spalten indiziere etc?



  • Jeder Index kostet Zeit beim Einfügen.
    Nur den Index machen den man auch wirklich abfragt.
    Datenbankperformance hängt nicht nur von den Tabellen ab.
    Auch das RDBMS spielt eine Rolle.
    Hier hilft auch nur testen.
    Das wichtigste ist mal zumindest bis zur 2 oder 3ten Stufe normalisieren.
    Die Tabellen klein halten. Also keine doppelten Daten. (Normalformen)
    MySQL versagt bei vielen Datensätzen z.B.

    Bei uns war der Umstieg auf MSSQL eine Steigerung um ca. 1000% auf ca. 50 Mill Rows.
    Löschen einzelner Rows ging bei MySQL schneller.
    Es gibt eben nicht nimm das und dann das.
    MySQL speichert jede Tabelle in eine Datei was Grundsätzlich schneller gehen sollte.
    MSSQL legt jede DB in einer Datei ab.
    10GB ist eben Grundsätzlich langsamer als 30 MB.
    Da kann man auch aber auch keine Aussage treffen das es langsamer ist.

    Normalisiere und dann setze die richtigen Indexe.
    Dann teste.
    DB-Design ist eben auch eine eigene Wissenschaft. Nicht Umsonst gibt es dafür Spezialisten welche nur das machen.



  • Hmm was bewirken den die indexe genau? was macht da ein DB system? ich hab mal spasshalber ne DB mit 4 mill. rows angelegt, mach ich ne abfrage über 500000 rows, geht das so 3-4 sek. PostgreSQL



  • http://de.wikipedia.org/wiki/Datenbankindex

    Gibst DU die 500.000 zurück?
    Wenn ja kannst du nicht von 4 Sekunden für die DB ausgehen.
    Die Übertragung dauert ja länger.
    Zähle einfach die Datensätze. Hole dir mit where eingie heraus und mache ein COUNT()

    Dann weiß t du wie lange ungefähr das RDBMS braucht um die Daten zu suchen.
    Weiß nicht ob PostG. da was Onboard hat. Bei MSSQL kann man das testen lassen.



  • Performancer schrieb:

    Hmm was bewirken den die indexe genau?

    Naja grob gesagt repräsentieren sie deine Datensätze anhand von B-Bäumen. Bäume haben halt die nette Eigenschaft, dass Suchen immer relativ schnell geht. Sie haben aber auch die andere Eigenschaft, dass Änderungen am Baum aber im Vergleich zu anderen Datenstrukturen wieder eher langsam sind.

    Siehe eben auch Unix-Toms vorhergehendes Posting.



  • ok danke schonmal und zwar folgendes:

    die Tabelle (4 mill. datensätze):

    CREATE TABLE t_loggingdata
    (
      mytimestamp timestamp without time zone DEFAULT now(),
      timeid bigserial NOT NULL,
      "type" integer,
      typeval double precision,
      CONSTRAINT "TimeKeyID" PRIMARY KEY (timeid)
    )
    

    INDEX:

    CREATE INDEX "TimeIDIndex"
      ON t_loggingdata
      USING btree
      (timeid);
    

    mach ich nun ne query:

    SELECT * FROM t_loggingData WHERE timeid > 100000 AND timeid < 500100;
    

    wird hier nun auf den index zurückgegriffen oder muss man das angeben irgendwie?



  • PRIMK haben automatisch einen Index.
    Deine Abfrage sollte sehr sehr schnell gehen.



  • naja bei den 500.000 datensätze die ich da selektiere geht es 15 sek.



  • noch was... bewirkt ein Index über mehrer spalten was?

    wenn ich bspw. oben in meiner tabelle alle werte mit Typx im bereich ID 100000 bis 5000000 suchen will?



  • Hallo,

    es gibt noch andere Möglichkeiten Postgres zu tunen.

    1. Postgres hat einen Query-Optimizer, d.h. verschiedene sql-abfragen, können intern die gleichen Operationen auslösen, z.B. verschieden-implementierte Cross-Joins. Im Endeffekt entscheidet die hinterlegende Struktur & Indizierung über die Performance.

    2. Postgres hat ein komplexes Caching-System.
    Da gibts u.a. den Disk-Cache und nochmal Caches für jeden postgres-Prozess und vielleicht wichtig zu erwähnen den "Query-Cache". Insbesondere wenn die Datenmengen größer sind, ist es wichtig, wenn sie noch in diesen Cache passen ... standard glaub ich 1MB <--- !

    Ich hatte mal den Fall von ca. 1.000.000 Inserts in einem Statement(transaction), nachdem ich den Query-Cache hochgestellt hab, liefs besser als 100mal 10.000 Inserts zu machen. ( interessant oder ?)

    Schau mal in der Richtung weiter ... und check mal die Größenordnungen deiner SQL-Operation. Wenn du es schaffst, alle Operation im Cache ablaufen zu lassen, bist du in der Hinsicht auf der sicheren Seite.

    Für kommerzielle Projekte gibts auch die Möglichkeit Postgres-Entwickler "zu mieten". Die tunen dann die DB oder Debuggen deine Postgres-Plugins.

    PostgresGreetz



  • Danke PostGreFan,

    ich hab grad ein andere Problem.. ich fülle grad die Table (siehe oben t_loggingdata) mit daten... über INSERT query.

    nun kommt ein fehler wenn i== 30.000.015 groß ist

    for (long i = 0; i < 100000000; i++)
                    {
                        command.CommandText = "INSERT INTO T_LoggingData(Type,TypeVal) Values (" + (i % 50) + "," + (float)(i / 3) + ")";
                        command.ExecuteNonQuery();
                        Console.WriteLine("Record {0}", i);
                    }
    
    ERROR [42601] ERROR: INSERT has more expressions than target columns;
    Error while executing the query
    

    versteh das nich:(



  • Problem oben gelöst:)

    Aber wie erhöhe ich den diskcache bzw. den Query- cache?



  • Findest du alles in der Doku, ansonsten schau mal in die Postgres-Config-Files.


Anmelden zum Antworten