SQLite plattgemacht ;-)
-
Hmmmm ... eigentlich geht's ja eher um Performanceunterschiede zwischen
einer EWS-Datenbank und einem speziell für genau einen Einsatzzweck konstruierten
System. Und es gibt noch andere Welten wie SQL
-
Was ist eine EWS-Datenbank?
-
EWS = Eierlegende-Wollmilch-Sau, so ein Mädchen für alles
-
lach, alles klar - also auf die Wollmilch-Sau wär ich jetzt im leben nicht gekommen
Darf ich trotzdem mal fragen wieso du für ein Webprojekt sqlite benutzt?
-
PRIEST schrieb:
lach, alles klar - also auf die Wollmilch-Sau wär ich jetzt im leben nicht gekommen
Muß nicht immer Denglish sein
PRIEST schrieb:
Darf ich trotzdem mal fragen wieso du für ein Webprojekt sqlite benutzt?
Tja, schwierig. Ich habe mal mit einem selbstgebastelten 8080 angefangen, dann
C64, den nachgebaut, dann irgendwann einen "richtigen" PC, in einer Firma als
Entwickler gelandet und C probiert. Hei war das auf einmal schnell gegenüber
dem GWBASIC :p .Dann wilde Mischungen aus dBASE und C, dann irgendwann mit dBASE IV voll auf
die Schnauze geflogen. Also nur noch C, in Verbndung mit Btrieve (genial).
Dann Webanwendungen, irgendeine Datenbank braucht man dann mal für einfachere
Anwendungen. Auf SQLite hat mich dieses Forum gebracht. Gut für's Web.Besser als die dauernde Patcherei wie mySQL etc.
-
Hm, interessant und die Webausgabe programmierst du dann in c?
Finde es nur etwas unüblich
Naja, wie dem auch sei - man schweift vom Thema ab ;)!
-
voll oldschool
-
Hm, interessant und die Webausgabe programmierst du dann in c?
Klar. Ich hatte mich mal eine Woche in PHP eingewühlt und dann doch lieber
das Original genommen. Ich finde, C ist für Webanwendungen besser geeignet
wie Scriptsprachen. Schon der Compiler bringt eine Menge (so Fehler wie
vergessen, eine Variable zu initialisieren, Tippfehler).Von PHP bis Ruby, Python kann jedes Scriptkiddie die Seite plattmachen -
Lücken gibt es genug. Bei kompilierten Sachen dürfte das schwieriger sein.Dazu kommen absolut schrullige Benutzerrechte seitens der Kundschaft, wirre
SAP-Aufrufe von außen und alles mögliche andere. Bei Benutzerrechten komme
ich an Sachen wo es schon schwierig wird, das auf Datenbanken abzubilden.
Teilweise muß ich die Scripts aus den Kundendaten generieren. Das kann PHP
nicht mehr.Von der Technik her sind es scriptgesteuerte C-Programme (Watcom C), die
HTML/CSS und JavaSscript dynamisch erzeugen.Es gibt auch Webstatistiken die behaupten (überprüfen kann ich das nicht),
C sei die meistverwendete CGI-Sache. Keine Ahnung ob das wirklich stimmt,
schnell, flexibel und einfacher wie zB PHP dürfte es sein.
-
Vorweg mal ein paar Fragen...
Die Datenbank passt nichtmehr als ganzes ins RAM, oder? So hab ich das nämlich verstanden.
Und du arbeitest vermutlich auch nicht mit SSDs, also Datenbank liegt auf drehenden Scheiben. Und auch nicht auf einem Array aus 100 solchen drehenden Scheiben, sondern irgendwas "normales" halt, also sagen wir bis max. 10 Platten in einem RAID 5 oder so.Wenn das stimmt, dann verstehe ich nämlich deine Argumentation nicht. Bzw. glaube dass du die falschen Gründe annimmst, warum deine massgeschneiderte Lösung schneller als die Eier-wollende Milchsau ist.
Scheppertreiber schrieb:
Das bringt dir nur was, wenn du die Record-Number bereits kennst.
Wenn du Zeilen anhand des Inhalts suchst, bringt es dir dagegen nix. Weil du sowohl mit fixer Datensatz-Länge als auch mit variabler Länge einen Index brauchst. Ob dort dann die Record-Number oder die Page-Number drinnen steht, ist ziemlich egal.Nein. Ein "echtes" DBMS lädt eine Seite, sucht darin den Record und muß
dann die einzelnen Felder suche und die Werte irgendwie laden (egal wie
es den Record findet). Das dauert naturgemäß länger wie ein einzelnes
lseek() mit nachfolgendem read() in eine Struktur wo die Felder ja bereits
"fest" enthalten sind.Eine Seite laden oder 50 Byte laden spielt überhaupt keine Rolle. Die Daten direkt in eine struct Lesen oder erst durch die Page-Struktur durcharbeiten und die Daten der gesuchten Zeile rekonstruieren ist auch egal.
Warum? Weil der Disk-Zugriff so langsam ist. Zwei Dinge:-
50 Byte von der Platte lesen geht nicht schneller als 8 KB (=Page-Grösse von MSSQL) von der Platte lesen. Der Grossteil der Zeit wird gebraucht um die Spur anzufahren und zu warten bis der gesuchte Sektor unterm Lesekopf vorbeikommt. Ob man dann einen Sektor (typisch 512 Byte=Minimum was die Disk lesen kann) oder gleich 16 Sektoren liest ist so-gut-wie egal.
-
Eine schnelle Platte schafft so an die 150 random IOs/Sekunde, 10 schnelle Platten in einem RAID Array also so 1500 IOs/Sekunde. Eine CPU macht in der Zeit ca. 2 Millionen Zyklen. Das sind 2 Millionen Zyklen in denen man die Records aus der Page raussuchen kann. Sollte sich leicht ausgehen.
Das Lesen eines grösseren Stücks sowie das Zerklauben dieses Stücks in einzelne Datensätze spielt also - bei random IO - quasi keine Rolle.
Die Suche nach dem Inhalt eines Feldes ist bei der Tabelle recht einfach.
Die Tabelle sei nach A sortiert. Verfahren: Gehe in die Mitte (recmax /2)
und vergleiche. Kleiner ? Ja -> in die Mitte der oberen Hälfte, nein->
nach vorne. etcpp. Mit memcmp() direkt das Feld gegen den Suchbegriff testen
ist trivial und schnell.Man nennt es binäre Suche
Braucht log_2(N) Schritte.
Wenn wir Caching erstmal ignorieren, dann macht das log_2(N) physikalische random IOs.
Sagen wir wir haben 130 Mio. Records, dann macht das etwa 27 IOs.Die Suche im Index eines DBMS funktioniert im Prinzip genauso, nur müssen
komplette Pages geladen und deren Inhalt auseinandergebastelt werden. Die
Laufzeit und den tree zu erstellen mal außen vor gelassen.Naja, funktioniert nicht ganz so.
B-Baum eben. Also ein Baum mit ganz vielen Verzweigungen pro Ebene, d.h. ganz wenig Ebenen.
Üblich ist eine Page bis zum Anschlag anzufüllen, so viel wie da reingeht so breit fächert der Baum.
Nehmen wir mal ne Hausnummer an, sagen wir eine Zeile im Index braucht 256 Byte - was schon einigermassen sehr viel wäre.
Dann passen in eine Page 8192/256 = 32 Zeilen.
Dann braucht die Suche log_32(N) Schritte = log_32(N) random IOs.
Bei unseren 130 Mio. Records wären das aufgerundet 6 IOs.So, nun zum Caching.
Wir können davon ausgehen dass die am häufigsten gebrauchten Seiten im Cache stehen, und daher extrem billig zu "lesen" sind. Beim B-Baum interessiert eigentlich nur wie viele komplette Levels in den Cache passen. Bei der binären suche ist es im Prinzip das selbe, nur dass hier die "Levels" verstreut im Datenfile liegen - der mittlere Datensatz ist Level 1, die Datensätze an Position 1/4 und 3/4 bilden Level 2 usw.Unterschied 1: bei der binären Suche wächst die grösse eines Levels immer mit Faktor 2, beim B-Baum mit Faktor 32 (oder mehr).
Unterschied 2: beim B-Baum wird die ganze Cacheseite genutzt, da innerhalb einer Seite immer Daten des gleichen Levels liegen. Bei der binären Suche, und vorausgesetzt man bekommt nicht die ganze Tabelle in den Speicher, verwendet man immer nur einen (!) Datensatz pro Cache-Seite.
Effekt: beim B-Baum wirst du max. 2 (in Extremfällen vielleicht 3 oder 4) Levels haben die nicht aus dem Cache bedient werden können. Bei der binären Suche viel mehr, die Anzahl der Levels die du im Cache halten kannst ist log_2(sizeof(Cache)/sizeof(Cache-Page)). Sagen wir wir haben 4 GB Cache und eine Cacheseite ist 4 KB gross, dann ergibt das ca. 20 Levels. 27-20 ist 7, und das ist mehr als 2
Also 7 physical IOs vs. 2 zum Auffinden eines Datensatzes.
Der B-Baum müsste also wesentlich flotter sein.
Was nun mit der schweinischen Milchwolle leider nicht mehr so gut funktioniert, ist das Lesen von vielen Datensätzen ab dieser Position. Weil eine solche Wollmilchdatenbank die Datensätze eben nicht in grossen Stücken sortiert auf der Platte ablegt.
Und genau das wird vermutlich der Punkt sein, wo deine Speziallösung punktet. Weil die Daten eben sortiert sind, und das Lesen der folgenden Datensätze keine random IOs mehr sind, sondern hier linear gelesen wird.Der Laufzeitunterschied ist heftig, schätze mal Faktor 100 bis 1000 (hab's noch nicht genau gemessen).
Dann miss es mal. Und vergleiche auch mal die Performance wenn du aus beiden Datenbanken jeweils nur einen Datensatz rausholst. Dann müsste die Datenwolle gut aufholen, wenn sie deine Speziallösung nicht sogar überholt.
Wobei es auch relativ einfach sein sollte einen B-Baum-artigen Index mit deinem sortierten Datenfile zu verbinden.
Die Lookups der ersten Zeile kannst du dann über den Index machen, und das lineare Lesen bleibt wie es ist.
-
-
Moin Hustbaer,
Dann miss es mal.
Ich hatte das nur sehr locker gemssen. Suchzeit bei meinem Systen (jeweils 3 Fundstellen) 0.14 sec,
bei der gleichen Datenmenge mit SQLIte hatte der Apache nach einigen Minuten etwas von einem 500 gemunkelt ...
(Feld-Wald+Wiesen-PC, Win XP prof, 4 GB RAM, Dualcore, RAID1, Apache 2).Interessante Ideen. Eigentlich logisch - ich muß das jetzt nur noch irgendwie mit der Praxis zusammenbringen.
Nach Deinen Ausführungen dürfte SQLite aber nicht dermaßen dramatisch einknicken.Eigentlich sollten die Sektoren mit den SQLite-Pages auch hintereinanderliegen, die Datenbank wurde ja neu
aufgebaut. Inwieweit da Ergebnisse des Caching eingehen weiß ich nicht. Nur, je weniger Daten umso mehr
dürfte auch in den Cache passen. Die Chance, daß eine Datei mit 1 MB komplett im Cache liegt ist naturgemäß
höher wie bei einer großen Datenbank.In der Firma läuft das auf schnellen PCs mit 10 Platten RAIDs, wir haben da auch ein 10 MBit Anbindung.
Bei unseren 130 Mio. Records wären das aufgerundet 6 IOs.
6 oder 27 I/Os dürften sich nicht so zwicken ...
Bei dem diskutierten System (es funktioniert da leicht anders), kenne ich die Datenmengen der einzelnen
vorkommenden Suchbegriffe - die habe ich mal in einzelne Dateien abgelegt (die größte wird 24 MB pro Jahr).
Die kann ich komplett in den Speicher laden, durchsuchen und habe dann sofort die Trefferliste. Von da
hole ich dann die Bestandsdaten.Wobei es auch relativ einfach sein sollte einen B-Baum-artigen Index mit deinem sortierten Datenfile zu verbinden.
Beim Herumprobieren mit SQLite habe ich alle Daten (nicht nur die Suchbegriffe) in einer DB. NUR die
Suchbegriffe dort speichern müßte ich nochmal probieren ...
("Bestandsdaten" bedeutet hier: Den Rest der Angaben aus den Rechnungszeilen, nicht die PDF/XML).Die Datenfiles sind "in order of einlesing", also unsortiert.
--
Suchbegriffe sind hier Kundennummer, Belegnummer, Artikelnummer (alle mit festen Längen).
Eingrenzungen durch Datum und Niederlassung sind möglich.
Bestandsdaten: Angaben wie Preise, Menge etc.