![]() |
AW: Tabellen für viele kleine Datensätze optimieren
Wofür benötigst du denn
SQL-Code:
?
`id` int(10) unsigned NOT NULL auto_increment,
Eigentlich ist die doch für nix gut ...
SQL-Code:
Um für das nächste Jahr eine neue Partition anzufügen einfach diesen Befehl ausführen
CREATE TABLE `history` (
`valueID` smallint(5) unsigned NOT NULL, `vdate` datetime NOT NULL, `maxValue` float NOT NULL, `meanValue` float NOT NULL, PRIMARY KEY (`valueID`,`vdate`) ) PARTITION BY RANGE(YEAR(valueDate)) PARTITIONS 3 ( PARTITION `p2012` VALUES LESS THAN (2013) ENGINE=MyISAM , PARTITION `p2013` VALUES LESS THAN (2014) ENGINE=MyISAM , PARTITION `pCurrent` VALUES LESS THAN (MAXVALUE) ENGINE=MyISAM ) ENGINE=MyISAM
SQL-Code:
Mit den Partitions hat sich dann das Problem mit der Datensicherung auch erledigt, denn nun gibt es pro Partition separate Dateien und wenn nur aktuelle Datensätze angefügt werden, dann bleiben die alten Dateien unberührt und müssen eben nicht mehr gesichert werden.
ALTER TABLE `values` REORGANIZE PARTITION pCurrent INTO
( PARTITION p2014 VALUES LESS THAN (2015), PARTITION pCurrent VALUES LESS THAN MAXVALUE ) |
AW: Tabellen für viele kleine Datensätze optimieren
Zitat:
Da man nur über vDate und ValueID abfragt, sollte ein Index reichen: ValueID+vDate (das meint Sir Rufo vermutlich mit 'PK über ValueID und vDate'. Hier steht jedoch nicht der Primary Key im Vordergrund, sondern ein nonunique index. Denn: Falls vDate in der Granularität nicht pikosekundengenau ist, wäre es denkbar, zwei Messwerte zum gleichen Zeitpunkt zu haben. Zumindest ausschließen kann man das nicht. MySQL kennt vermutlich keinen Clustered Index, so wie MS SQL-Server. Gäbe es jedoch ein ähnliches Konzept, wäre ein Clustered Index über vDate+ValueID noch schneller, da bei den Abfragen nur ein Clustered Index-Seek/Scan ausgeführt wird. Wenn man beim Auswerten über einen Zeitraum auch 'nur Morgens zwischen 8-10' abfragen will, dann Datum und Uhrzeit getrennt, sonst als Timestamp. Grundsätzlich würde ich trotzdem das Konzept mit den redundanten Aggregationstabellen verfolgen, es macht einfach Spaß, in Echtzeit in die Daten zu zoomen und zu scrollen, ohne irgendwelche Last zu produzieren. Man sollte ja auch bedenken, das man entweder eine separate Auswerte-DB erstellt, oder -wenn man das nicht macht- den Server mit Auswertungen nicht zu sehr belastet. Das wäre dann ziemlich blöd, wenn er gerade wie ein blöder Daten fressen soll, aber nicht kann, weil eine Tabelle wegen einer Auswertung gelocked ist. Zitat:
|
AW: Tabellen für viele kleine Datensätze optimieren
Södale, ihr habt mich ganz gut davon überzeugen können, dass eine Spaltung in mehrere Tabellen nicht das Gelbe vom Ei ist. Den aktuellen PK, also das autoinc Feld, kann ich hier tatsächlich weg lassen. Hab mir das angewöhnt, weil ich es für unsere Hauptanwendung zwingend brauche, das hier ist aber ausser der Reihe. Der fliegt also schon mal.
Partitioning klingt sehr praktisch, danke auch für das Beispiel als Code. Gelesen habe ich ein wenig drüber, genutzt bisher nicht. Das einzige was mich an der gezeigten Variante stört ist, dass ich quasi jedes Jahr ein "Pflege-Statement" ausführen muss, was mit Sicherheit spätestens nach dem 2. Jahr im Tagesgeschäft unter geht. Kann man es so deichseln, dass mit Beginn eines neuen Jahres automatisch eine neue Partition begonnen wird? Bezüglich Index: Hier fehlt mir auch noch ein wenig Erfahrung um genau sagen zu können, welche Indizes ich hier wirklich brauche. Einen PK braucht es glaube ich wirklich nicht, aber wenn, dass wäre vdate+valueID ein guter Kandidat. Die kürzesten Intervalle von Einträgen mit derselben valueID sind 1 Minute, also garantiert verschiedene Timestamps. Bisher habe ich recht naiv immer über die einzelnen Felder einen Index angelegt, die ich nachher in meinen WHERE-Klauseln benutze. Das wäre in diesem Fall vdate und valueID, auch in Kombination. Es wird nachher sicherlich ein Statement der folgenden Struktur genutzt um die Daten zu holen:
SQL-Code:
Edit: Der Join macht eigentlich kaum Sinn, da ohnehin bei der Ausgabe nach valueID, vdate sortiert werden sollte. Die Messstellennamen kann ich mir also auch billiger in einem separaten Statement holen und als Überschrift/Legende einsetzen. Die müssen nicht bei jedem Datensatz einzeln bei stehen.
SELECT
h.vdate, h.valueID, h.maxValue, h.meanValue, v.valueName FROM history h JOIN valueList v ON h.valueID = v.id WHERE (h.vdate BETWEEN :sDate AND :eDate) AND (v.valueID IN ({idListe})) Ist es da besser einen kombinierten Index auf vdate und valueID zu legen, oder jedes Feld seinen eigenen? Oder gar beides? Welche Art von Index eigenet sich hier? (Beide Felder sind für sich genommen non-unique, in Kombi aber unique.) Mein MySQL Tabellen-Tool bietet mir hier die Optionen: Index Kind: Index, Primary, Unique, Fulltext, Spatial Index Type: Default, BTree, Hash, RTree Ich habe mich bisher schämlich wenig damit befasst, welche Index-Arten für welche Fälle geeignet sind :oops: Die angesprochene Trennung von Datum und Uhrzeit wird nicht nötig sein. Wenn, dann werden immer komplette Zeiträume am Stück abgefragt. Eine separate Tabelle mit Daten zur Anzeige, und Umschaltung bei Zoom klingt zunächst sehr nett, aber ich weiss nicht, ob ich es mir leisten kann auf Dauer mehrere Granularitäten vollständig vorzuhalten. Klar ist, dass ich bei einem Zoom, der pro Pixel im Graphen z.B. 30min entspricht nicht alle minütlichen Werte übers Netzwerk jagen lassen wollen würde. Das Problem habe ich mir bisher nicht genauer angesehen, und hatte gehofft eine Möglichkeit zu finden vielleicht angeben zu können, dass ich nur jeden 2. oder 3. Datensatz einer Ergebnismenge vom Server bekomme. Gibt es sowas? Wenn nicht, werden redundante Tabellen leider doch wieder interesant, weil vermutlich die letzte Möglichkeit dann. Danke zwischendurch schon mal für die rege und produktive Teilnahme! :dp: |
AW: Tabellen für viele kleine Datensätze optimieren
Du kannst beim MySQL Events definieren, die zu einem bestimmten Zeitpunkt laufen, also erstellst du dir einen Event, der einmal im Jahr losläuft und die entsprechende Partition neu erstellt.
Hier auch ein entsprechender ![]() Der Pflegeaufwand geht also auch gegen Null :) |
AW: Tabellen für viele kleine Datensätze optimieren
Zitat:
Zitat:
|
AW: Tabellen für viele kleine Datensätze optimieren
Bei den Datenmengen würde ich mit dem automatischen Partitioning vorsichtig sein. Es wird wohl in der Regel problemlos funktionieren, aber ich würde das lieber auf Termin legen und unter eigener Aufsicht laufen lassen. Ist aber Geschmackssache.
Was für dich auch interessant sein könnte, sind Indexed Views. Dort hast du dann automatisch deine aggregierten Werte und brauchst keine Trigger oder Events. Es gibt aber wohl ![]() |
AW: Tabellen für viele kleine Datensätze optimieren
Zitat:
|
AW: Tabellen für viele kleine Datensätze optimieren
Zitat:
|
AW: Tabellen für viele kleine Datensätze optimieren
Da ich bisher nur gute Erfahrungen mit views gemacht habe, würde ich diese auch bevorzugen (oracle).
Jedesmal wenn ich irgendwelche kumulierten Daten in die Finger bekomme, gibt es ein paar Abweichungen, weil immer der eine oder andere Job nicht gelaufen ist oder einen Fehler hatte oder... (Es kommt immer auf die Daten - die gespeicherten und die gefragten - an) Gruß K-H |
AW: Tabellen für viele kleine Datensätze optimieren
Aber bei vielen Daten ist ein View doch auch nicht so gut, wenn er erst stundenlang rumrechnen würde, bei jeder Abfrage.
Drum auch der Vorschlag mit dem Data-Warehouse. Die Dinger sind erstmal für viele Daten ausgelegt und sie bieten auch sowas wie Views, nur daß Diese job-/zeitgesteuert die Daten der Ansichten vorberechnen, was dann die Abfragen schneller macht. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 22:18 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz