Hallo Zusammen
Ich habe ein Leitsystem mit einer M-CPU und max. 16 IO-Baugruppen
entwickelt man spricht bei dieser Zusammenstellung von einer Komponente
und ich werde für mein Vorhaben in etwa 20 Komponenten benötigen. Um
diese Anlagen parametrieren zu können habe ich ein Tool in C#
geschrieben und eine Access (2013) Datenbank für die Parameter
verwendet. Aber leider habe ich den Umfang der Datensätze unterschätzt
und bei 20 Komponenten komme ich ca. auf 350000
(dreihundertfünfzigtausend) Datensätzen in der Parameter-Tabelle und da
gehen einige Funktionen sehr zäh. Bei zwei Komponenten in der Datenbank
habe ich eine Funktion die ca. 15 Sekunden benötigt und mit 20
Komponenten habe ich sie nach 7 Minuten abgebrochen will ich dachte das
sich der PC aufgehängt hat.
Ich verwende reader = cmd.ExecuteReader(); und cmd.ExecuteNonQuery für
die Bearbeitung der Datensätze.
Macht es Sinn auf eine andere Datenbank umzusteigen oder welche
Möglichkeiten habe ich um die Laufzeit der Datenbankbearbeitung
brauchbar zu gestallten?
Bitte um eure Hilfe. Danke.
Lg.
Johann K.
indices auf felder in where-bedingungen. falls ms sowas unterstützt:
b-tree auf felder mit hoher kardinalität, bitmap auf solche mit
niedriger.
ohne indices hast du bei jeder abfrage full table scans.
wobei ich mssql nur als "schlechte datenbank", bzw. schlecht entwickelte
frontends kennegelernt habe - ich komme eigentlich aus der oracle ecke
mit ein wenig rumspielerei mit mysql/mariadb.
Klatec schrieb:> und eine Access (2013) Datenbank für die Parameter> verwendet.
wenn ihr Access wirklich nur als DB nutzt, dann würde ich vorschlagen
auf MS-SQL zu wechseln. Bis 2GB Datenbank ist es kostenlos, ist ein
Datenbanksystem was sehr gut skaliert und nicht bloss ein Treiber wie
bei Access, wo es nicht mal einen wirklichen Prozess gibt.
Wir haben dort weiter mehr als 500.000.0000 Einträge in einer Tabelle
und es geht flott.
Es gibt zu sicherlich jeder Datenbank Texte über die Optimierung von
Abfragen und die Gestaltung der DB hinsichtlich Indizes. 350k Einträge
sind recht wenig, aber ohne Index, aber dafür umfangreicher Bestückung
mit teuren Funktionen im WHERE. zwingt man eine DB trotzdem in die Knie.
c.m. schrieb:> wobei ich mssql nur als "schlechte datenbank", bzw. schlecht entwickelte> frontends kennegelernt habe
Yep. Webentwickler und Datenbanken sind oft wie Hund und Katz. ;-)
Klatec schrieb:> [...] und eine Access (2013) Datenbank für die Parameter> verwendet. [...]> Macht es Sinn auf eine andere Datenbank umzusteigen?
Ja.
fast egal welche, nimm was dir am besten passt. Selbst sqlite wird
besser performen.
A. K. schrieb:> Es gibt zu sicherlich jeder Datenbank Texte über die Optimierung von> Abfragen und die Gestaltung der DB hinsichtlich Indizes. 350k Einträge> sind recht wenig, aber ohne Index, aber dafür umfangreicher Bestückung> mit teuren Funktionen im WHERE zwingt man eine DB trotzdem in die Knie.
ja, das kann ACCESS auch. Aber das dumme an ist, das es keinen
Serverprozess gibt. Der Treiber ist die Datenbank und öffnen die Datei
direkt. Sobald ein paar mehr Leute die DB nutzen, muss die ganze
Synchronisierung übers Dateisystem laufen. Auch muss jeder Treiber die
Daten selber cachen weil es kein gemeinsamen ram gibt.
Ein Wechsel auf mssql sollte um unproblematischsten sein, weil beide
doch ein paar Ähnlichkeiten haben. Bei MySQL und Postgresql könnte das
etwas mehr aufwand sein. Und da es eh C# ist, passt doch ein
MS-Datenbank recht gut dazu. Dort kann man dann sogar sehr effiziente
Bulk-Operationen nutzen.
c.m. schrieb:> wobei ich mssql nur als "schlechte datenbank", bzw. schlecht entwickelte> frontends kennegelernt habe - ich komme eigentlich aus der oracle ecke> mit ein wenig rumspielerei mit mysql/mariadb.
meinst du jetzt ACCESS oder MSSQL? MSSQL ist schon ein guten DB-System.
Mich nervt Oracle da schon viel mehr, da geht alles irgendwie
umständlich.
Hallo Planlos
Ich tu mir etwas schwer dich mit Planlos anzusprechen wenn da wer
planlos ist bin das sicher ich.
Nein ich habe keine Indexe angelegt ich habe schon davon gelesen aber
bei den Datenbankanwendungen die ich bisher gemacht habe war die
Zugriffszeit kein Thema und daher habe ich mich damit nicht beschäftigt.
Wie du schon bemerkt haben wirst bin ich jetzt nicht der große
Programmierer und danke dir für deinen Tipp. Ich werde versuchen diesen
umzusetzen.
Schönen Abend.
Johann K.
Peter II schrieb:> MSSQL ist schon ein guten DB-System.
MS SQL ist völlig ok, insbesondere innerhalb der Limitierungen der
kostenlosen Version (Express?). Ist halt ein etwas grösserer Klops auf
der Platte als MySQL und wenn man irgendwann doch die Limitierungen
überschreiten sollte, dann wärs besser, wenn man sich über die
Lizenzierung vorher Gedanken gemacht hat.
Zu beachten ist, dass bei der Grössenbeschränkung meiner Erinnerung nach
die Transaction Logs mitgerechnet werden. Wenn man ausgiebig modifiziert
und mit vollem Logging arbeitet spielt das schon eine Rolle.
> Mich nervt Oracle da schon viel mehr, da geht alles irgendwie> umständlich.
Oracle wäre hier mit Kanonen auf Spatzen geschossen und würde
voraussichtlich eher in einem Rohrkrepierer enden als den Spatz töten.
Das ist ein System für Experten.
A. K. schrieb:> MS SQL ist völlig ok, insbesondere innerhalb der Limitierungen der> kostenlosen Version (Express?). Ist halt ein etwas grösserer Klops auf> der Platte als MySQL und wenn man irgendwann doch die Limitierungen> überschreiten sollte, dann wärs besser, wenn man sich über die> Lizenzierung vorher Gedanken gemacht hat.
aktuell sind bis zu 10GB je Datenbank drin.
http://www.microsoft.com/en-gb/server-cloud/products/sql-server-editions/overview.aspx
Und wenn man will, legt man jede Tabelle in eine extra Datenbank. Was
dann nur nicht geht sind contraints. Sonst ist das auch kein Problem
Datenbankübergreifend abzufragen.
Klatec schrieb:> Nein ich habe keine Indexe angelegt ich habe schon davon gelesen
Nicht nur lesen, auch beherzigen.
Wenn du in einem Katalog einen bestimmten Artikel suchst, tust du dich
ohne sortierte Liste der Warengruppen/Artikel auch fürchterlich schwer,
einen bestimmten Artikel zu finden. Alternativ kann der Datenbestand
natürlich auch passend sortiert sein. Das kommt auf die Daten und das
dahinter stehende Datenmodell drauf an. Aber 350000 Datensätze wild
durcheinander mit möglicherweise noch irgendwelchen aufwändigen
Berechnungen in der Abfrage, zwingen fast jeder Performance in den
Keller.
Man möge sich mal mit dem MySQL-Ableger "MariaDB" befassen. Insbesondere
die Möglichkeit, notfalls für jede einzelne Tabelle eine eigene
Storage-Engine (außer MyISAM oder InnoDB gibts nämlich noch reichlich
andere, z.B. "Memory") zu definieren, verleiht gewissermaßen "Flügel"
... !
Frank E. schrieb:> Man möge sich mal mit dem MySQL-Ableger "MariaDB" befassen. Insbesondere> die Möglichkeit, notfalls für jede einzelne Tabelle eine eigene> Storage-Engine (außer MyISAM oder InnoDB gibts nämlich noch reichlich> andere, z.B. "Memory") zu definieren, verleiht gewissermaßen "Flügel"> ... !
ob das für Ihn sinnvoll ist?
[...]
It is best-used for read-only caches of data from other tables, or for
temporary work areas.
[...]
für die paar Daten kann er jeden DB nehmen, es müssen nur die Daten
passend indiziert sein.
Hallo Zusammen
Ich bin überwältigt welch intensive Diskussion meine Frage vom Zaun
gebrochen hat.
Ich muss zugeben das mich einige Antworten überfordert haben aber ich
werde jetzt einmal Schritt für Schritt versuchen meine Tabellen zu
indizieren und werde mir dazu aus dem www einige Beispiele an sehen. Ich
bedanke mich für eure Hilfe.
Lg.
Johann K.
Peter II schrieb:> Felix A. schrieb:>> Mal so nebenbei: Access ist KEINE Datenbank>> wie kommst du darauf?
Doch Peter, auch Access ist eine Datenbank, schliesslich bezeichnen auch
viele VSAM und ISAM als Datenbanken
:-)
Der Andere schrieb:> Doch Peter, auch Access ist eine Datenbank, schliesslich bezeichnen auch> viele VSAM und ISAM als Datenbanken
Die Microsoft Jet Engine, auf der Access aufbaut, kann man als RDBMS
betrachten. Relationale Datenbanknutzung über SQL ist drin,
Transaktionsverarbeitung und Zugriffsrechte ebenfalls.
Access ist aber kein Datenbank-Server wie MySQL, MS SQL oder Oracle und
findet bei gleichzeitigem Zugiff durch mehrere Anwender sehr schnell
seine Grenzen. Dafür ist es nicht konstruiert, ebensowenig wie das im
Ansatz grob ähnliche SQLite.
https://en.wikipedia.org/wiki/Microsoft_Jet_Database_Engine
Felix A. schrieb:> Eine exakte Erklärung, weshalb das so ist, finde ich gerade nicht.
Weil Access eine Anwendung ist und nur dessen Jet Engine ein RDBMS - und
die Jet Engine steht drin in der Liste.
SQLite und Microsofts Jet Engine sind Programmbibliotheken, die es
Programmen ermöglichen, wesentliche von klassischen RDBMS zur Verfügung
gestellte Features in Programmen zu nutzen, ohne dafür einen separat
arbeitenden Datenbankserver einrichten zu müssen. Zugriff durch mehrere
gleichzeitig laufende Instanzen ist dank dieser Arbeitsweise allenfalls
über sehr grobes Locking auf Fileebene möglich, wenn überhaupt.
Access wiederum setzt auf die Jet Engine eine Anwendung oben drauf.
Insoweit ist Access genau genommen kein Datenbanksystem, sondern eine
Anwendung mit integrierter Datenbank-Engine. Und steht deshalb nicht als
"MS Access" drin, sondern als "Jet Engine".
Man kann Access auch als Frontend zu anderen RDBMS verwenden, also z.B.
Oracle dahinter an Stelle der Jet Engine.
Georg schrieb:> Zwei davon sind definitiv zuviel für sicheren Betrieb.
so schlimm ist es nun auch wieder nicht. es können schon mehre Leute in
einer ACCESS db gleichzeitig arbeiten - nur schneller wird es dadurch
nicht. Stabil ist es aber trotzdem.
Aber Jet Engine ist File-basiert, jeder Prozess liest Seite aus dem
DB-File und kann (sinnvoll) nur auf Ebene dieser DB-Seiten in der Datei
sperren. Und all das geht üblicherweise übers Netzwerk.
Bei SQL-Server gibt es EINE Prozess, der die Files verwaltet/seitenweise
cached und der kann Sperren auf Satzebene benutzen. Den Unterschied
merkt man besonders bei parallelen Zugriffen. Es fließt auch nur das
Ergebnis über's Netzwerk. Ich kann mich an ein Experiment in einem
O'Reilly Buch erinnern, wo ein Webserver 10x soviele Anfragen in einem
10-tel der Zeit bedient hat. Rein durch Umstieg Jet auf SQL-Server.
Beide via JDBC.
Ich habe mal vor langer Zeit mit Access als Datenspeicher gearbeitet, so
richtig problematisch wurde es erst als die Datei über 100 MB groß
wurde.
Aktuell verwende ich Sqlite auch mit 90.000 Datensätze und 10
Datenfelder pro Datensatz, also 900.000 Daten. Dies läuft alles im
Sekundenbereich, also absolut unproblematisch.
Wie ist denn ein Datensatz aufgebaut? Und wie sind denn die Abfragen
aufgebaut, werden dort eventuell viele Verknüpfungen unter mehreren
Tabellen gefordert?
Vielleicht kannst Du beispielhaft mal die Struktur der Datenbank
darstellen, so dass man das ganze mal simulieren kann (nur in Sqlite,
Access macht für mich keinen Sinn). Und dann auch mal formulieren, wie
die Abfragen aussehen. Vielleicht ist es nur ein Problem der
Datenbankstruktur.
Gruß
Marvol
Hallo Marvol
Alle Abfragen beginnen mit in der Tabelle KOMP (Komponnenten Nr.)
Tab KOMP
RNr KNr StaNr Bez SetNr
10 254 255 Test 16
10 25 255 Test25 17
Hier ermittle ich die SetNr mit Hilfe der Regions- und Komponentennummer
die ist für jede Komponente eindeutig und schreibe sie in eine Variable.
Mit dieser SetNr werden dann in der Tabelle Value1 alle nötigen Abfragen
durchgeführt.
Die Tabelle Value1 hat dann 52 Spalten und ca. 350000 Datensätze bei 20
Komponenten.
Die meisten Datensätze haben die Ausgabebaugruppen knapp 2000.
In der Tabelle Value1 wird durch die Spalten SetNr und BGNr
(Baugruppennummer) und je nach Parameter gibt es dann noch 2 bis drei
Spalten nach denen gefiltert wird. Aber die Abfragen erfolgen immer nur
über eine Tabelle.
Ich hoffe ich konnte es einiger maßen erklären.
Lg.
Johann K.
A. K. schrieb:> Weil Access eine Anwendung ist und nur dessen Jet Engine ein RDBMS - und> die Jet Engine steht drin in der Liste.
Nicht nur die, man schaue mal unter 'M' nach:
"Microsoft Access – das relationale Datenbanksystem von Microsoft für
PCs"
Ist ja sehr lustig wie viele hier gleich mit der
Wechsel-die-Datenbank-Keule um sich schlagen - mit absolut 0
Informationen wie seine Datenbank aussieht und wie er darauf zugreift
(nach eigenen Aussage ist er ja nicht so der Crack oder?)
Regel bei Datenbanken:
-Vermeide viele kleine iterative Selects/Abfragen um dein Ergebniss
zusammen zu sammeln - das ist in jeder Datenbank absolut tödlich - SQL
ist sehr mächtig
-arbeite mit Indices - aber nicht einfach wild einrichten - zu viel ist
auch nicht gut
-nicht immer alles mit TEXT oder sonstige "Übertypen" für Zahlen usw.
benutzen - kostet alles
zu deinen Tabellen/Queries
am besten schreibst du die mal sauber auf
Tabelle1
TYP feld1
TYP feld2
usw.
und die Tabellenbezüge
und dazu GENAU die Abfragen/Ablauf die du tätigst/machst - es kommt auf
die Details an - moeglicherweise einfach zu iterativ
du koenntest deine Beispiel auch einfach für SQL Fiddle vorbereiten dann
kann man gleich damit spielen
http://sqlfiddle.com/#!9/dcb16/1
Hallo Zusammen
Ich möchte mich bei allen sehr herzlich für eure Unterstützung bedanken.
Die Lösung war die Indizierung und nun flutscht's, weit schneller als
vorher mit nur einer Komponente. Ich bin begeistert. Danke.
Lg.
Johann K.
Klatec schrieb:> Ich bin begeistert. Danke.
Schön dass es so gut klappt.
Wenn deine Datenbank dann auf 350 Mio Einträge angewachsen ist, sprechen
wir uns wieder :)
>Die Lösung war die Indizierung und nun>flutscht's, weit schneller als>vorher mit nur einer Komponente.
wenn du uns jetzt noch deine SQL-Abfrage(n) usw. zeigst lernst du dann
vielleicht auch gleich was für die nächste, noch größere DB - wo dann
z.B. nur ein Index hinzufügen auch nicht mehr reicht
Test87 schrieb:> wenn du uns jetzt noch deine SQL-Abfrage(n) usw. zeigst lernst du dann> vielleicht auch gleich was für die nächste, noch größere DB - wo dann> z.B. nur ein Index hinzufügen auch nicht mehr reicht
bei einer Tabelle und einer Abfrage - kann es nicht einen sinnvollen
index gehen. Maximal kann man noch nach Typ unterscheiden( clustered,
unique ... )
von Klatec so geschrieben
>Hier ermittle ich die SetNr mit Hilfe der Regions- und Komponentennummer>die ist für jede Komponente eindeutig und schreibe sie in eine Variable.>Mit dieser SetNr werden dann in der Tabelle Value1 alle nötigen Abfragen>durchgeführt.
schreibe sie in eine Variable...alle nötigen Abfragen
das könnten auch mehrere sein - eine einzige reicht - aber
es ist nicht klar ob es so ist