![]() |
Datenbank: MSSQL • Version: MSADO15.DLL • Zugriff über: ADO
Ado Performance steigern
Hallo DP'ler,
das erste mal, daß ich eine Frage einstelle. Leider muß ich etwas ausholen: Bin am basteln, wie ich unsere zwei teuren Brüder FireDac/UniDac toppen kann. Ich bin mit dem jetzigen Stand von Zeos-7.2 eigentlich ziemlich zufrieden. DevArt brauch ich nicht mehr nachzufragen, da as zu weit hinten liegt. FireDac ist jedoch in gewissen Bereichen noch interessant. Ich habe alle Treiber, sagen wir mal, nach Wunschliste, abgearbeitet. Zeos hat eigene Benchmark-Tests, um Performance-Vergleiche auszuführen. Der Sprung von <7.2 zu 7.2up ist gewaltig, je nach Anforderungen der Tests habe ich einen Performance-Zuwachs von Faktor 4 bis 20. Aber darum geht's jetzt nicht. Am Ende steht da noch das Zeos-Protokol "ADO" im Raum. Derzeit benutze ich am liebsten die Tests von ![]() Diese Test laufen ohne TDataSet oder der gleichen, direkter Zugriff auf's AdoRecordSet bzw. AdoCommand. Die Synopse Tests sind simpel und benchmarken 5000 Inserts und Lesen diese wieder. Wer's wissen will: sie basieren auf reiner UTF8-codierung, Ist aber hier im Kontext nicht notwendig, da ja nach nicht ADO-Treiber die Performance x10-20 dagegen steht. Das brachte mich zum Grübeln. Entweder ist MSSQL einfach nur 'ne Schnecke oder de Hammer hängt ganz wo anders! Also begann ich im Zeos-Projekt zu suchen und zu basteln.. Ohne wirkliche Erfolge, wenn ADO zum Tragen kam. Vor drei Wochen schenkte mir mein Vater mal wieder eines seiner alten Bücher: ADO-Programmierung von MS Press, Autor ist David Sceppa. Habe mir die 300 Zeiten mal schnell komplett gegönnt, um etwas zu lernen. Erfahren wollte ich freilich, wie man ADO "tunen" kann und was der beste Weg für BATCH Executions wäre: ADO unterstützt das nur via AdoRecordSet -> implementiert -> hust, prust. Da kann ich's auch manuell Row By Row machen! -> Implementiert -> 20% schneller als übers AdoRecordSet. Erstes Zahlen zum Vergleich & Merken von den Synopse-Test (inserts/Sekunde VOM LESEN WILL ICH WIRKLICH NOCH GAR NICHT REDEN!): Zitat:
Somit begann ich zu überlegen, wo denn dieser unglaubliche DROP her kommt: Verschieden Versionen von SLQLNCLI .... nö keine merklichen Unterschiede. Dann folgte nur die Logik. ADO ist nicht's weiter als ein End-User freundlicher Wrapper für OleDB. Alles in schöne Interfaces verpackt, Locale Typen kein Problem usw.. Was wäre, wenn ich via AdoCommand direkt mit OleDB kommunizieren könnte? Umgehe mal den ganzen OleVarinat Quark, und liefere, was der eigentlich Treiber will? Erster versuch, klappt. Jedoch haben wir Tests, welche mich Zwangen alles nochmal umzuwerfen -> never discuss with the users! Zweiter Versuch, ADO im Vordergrund, via QueryInterface das AdoCommand umgangen und nur noch mit ICommand/ICommandText/ICommandPrepare/IAccessor all meine Wünsche ausgeführt: ist 5-10%langsamer als VS1 mit OleDB. Resultate(FÜR JEDEN SELBER MESSBAR): Zitat:
Wem die Test's nicht gefallen: Schaut mal im 7.3er SVN von Zeos, wie man das ADO gequarke umgeht, implementiert es & vegleicht selber. ES rockt mit direkt OleDB und hinkt mit ADO. Nun die eigentliche Frage, wenn mann bedenkt, daß Zeos nur über Defaults das Treibers zugreift, das Handbuch darauf vereist, daß ADO in JEDEM Falle die best mögliche Einstellungen ja nach Provider trifft... Wer kennt sich mit ADO aus? Was geht da noch? Übersehe ich Settings, die ich nicht kenne und ich im MS-Buch nicht zu finden vermag? Wo und wie muß ich die Knöpfe drücken, um ein bischen zu Lächeln? Wäre über jeden "sinnvollen" Gedanken erfreut. Im Buch beschrieben steht nich viel: "Über meine gesamte Zeit, habe ich noch nie veränderte Properties gesehen"... "mit ADO lassen sich High-Performance erstellen"....BlaBla Alles vom MS Autor. Was kann man tun, um wenigstens im Ansatz aus 'nem "Veralteten, lahmenden Esel" einen "galloppierendes Pferd" zu machen? ICE erwartet ja keiner, wenn mann bedenkt, das ADO eigenen Speicher reserviert & OleDB auch noch dazu und DANN erst kommst du! Michael Ps. Direkt OleDB-Wrapper ist fast fertig für 7.3. Dennoch ist die Frage zwar nostalgisch aber ernst gemeint! Was geht denn da noch? mein Connect String: Zitat:
|
AW: Ado Performance steigern
Wäre es nicht ratsam erstmal die Grundperformance des MSSQL-Servers zu bestimmen? Wie schnell kann der denn wirklich 5000 Zeilen schreiben/lesen.
Wenn das feststeht, dann macht man den Test über die Zugriffskomponenten und sieht wieviel Prozent da verschluckt werden. Erst dann kann man auch eine echte Aussage machen. Bis jetzt ist es Kaffeesatz lesen ;) PS: SQLEXPRESS - ist auch performancetechnisch nicht mit dem Server zu vergleichen! Lies dir mal die Beschränkungen dazu durch. |
AW: Ado Performance steigern
Danke für erste Anteilnahme :?.
Vielleicht habe ich zu weit ausgeholt? Ich wollte keine Performance von MSSQL o. andere Server an sich vergleichen oder in Frage stellen, sondern habe ADO(AdoCommand) mit seinen Parametern dem Prepare usw. mit einem direkten OleDB(noch nicht mal sqloledb, welches MSSQL-spezifisch wäre) Zugriff verglichen. Somit spielt also was kann MSSQL oder was can die DevExpress-Version für mich keine Rolle. Nochmals zum Verstädnis, für Ole, ich erschaffe ebenfalls ein AdoCommand, und weise die aktive Connection zu. Dann jedoch endet mein ADO-Code (nur für Updates derzeit) und ich leite sämtliche Ole-Interfaces, welch ich benötige via Supports() oder QueryInterface ab, um sicher zu stellen, daß der Ole-Provider auch kann, was ich machen möchte.. Um die updates machen zu können, ist wesentlich mehr Code notwendig, aber die voran genannten Zahlen können sprechen.. |
AW: Ado Performance steigern
Hmm... Wenn es performancetechnisch eine Rolle spielt, wie schnell 5000 Inserts sind, dann stimmt was mit meinem Design nicht. Es ist eigentlich immer falsch, 5000 Inserts aus seiner Software heraus zu machen, wenn die Performance wichtig ist. Dann musst Du zu BULK INSERT greifen, bzw. (bei 5000 vermutlich einfacher und schneller) auf Dataset-Parameter (also eine @Tabelle). Aber weder das eine noch das Andere wird von ADO nicht unterstützt (ADO wird imho eh nicht weiterentwickelt).
BULK INSERT bekommst Du aber mit einem einfachen ADOCommand hin. Zum Thema Schnecke: Beim Einfügen ist FB wirklich ziemlich schnell, aber dafür kann man beim Löschen von Datensätzen in den Urlaub fahren. FB eignet sich imho also nicht für eine DB, bei der sehr viele Daten geschrieben (das geht schnell) und auch wieder gelöscht werden (z.B. eine Messdatenbank, bei der z.B. Daten älter als 10 Tage gelöscht werden). Oder FB ist auch beim löschen sauschnell, aber ich bin zu blöd dafür. Deine Messungen erinnern mich aber eher daran, herauszubekommen, ob man einen Ferrari oder einen Maserati schneller anschieben kann und wie viel Heu in die einzelnen Autos passt: Wenn Du also Provider vergleichen willst, dann musst Du das schon entweder mit irgend einer Referenz-DB machen (also z.B. FB) oder Tests für viele RDBMS schreiben. |
AW: Ado Performance steigern
Zitat:
Zitat:
Zitat:
Zitat:
Die DBs nehmen sich nicht viel. Viel wichtiger ist der eigene Quellcode. Wenn man hier murks macht kann selbst der größer Cluster-Server nix mehr reisen wenn auf DB-Seite Grundvorrausetzungen wie genügend zugewiesener Speicher und (genügend) schnelle Festplatten dran hängen vorhanden sind. Als wir (vor Jahren) einen Prepared Statement-Cache eingebaut haben und dann noch auf selbstgeschriebenen "Bulk INSERT" umgestiegen sind hatten wir einen gewaltigen Performancegewinn - egal welche DB. Bei MS SQL haben wir die ADOExpress/dbGo rausgeschmissen uns sind aufs ADO-Interface umgestiegen. Hat hier auch viel gebraucht. |
AW: Ado Performance steigern
Zitat:
Zitat:
Zitat:
Und nein: Du bekommst einen BULK INSERT nicht nur "fast", sondern vollständig hin. Wenn Du Zugriff auf das Serververzeichnis hast, schreibst Du die Daten dort in eine Datei und führst ein BULK INSERT aus. Geht das so nicht, dann über BCP.EXE. Das liest die Daten lokal ein und bläßt sie übers Netz direkt in den Server. Eventuell kommst Du über Delphi auch direkt an die SMO, aber da bin ich mir nicht sicher, weil das normalerweise für .NET ist. In den SMO ist ein SqlBulkCopy-Objekt. BULK INSERT lohnt sich aber erst bei Batches > 5000 Records. Dafür dann aber mit 10k-100k Records pro Sekunde. SELECT mit OPENROWSET ist auch noch eine Variante. Hab ich aber noch nicht probiert. |
AW: Ado Performance steigern
Wenn man die Performance der Zwischenschicht ermitteln will, dann teste ich doch nicht den BestCase, sondern den WorstCase. Allerdings ist es entscheidend, wie schnell wird dieser WorstCase ohne und mit Zwischenschicht verarbeitet. Aus dem Unterschied kann ich dann den Overhead der Zwischenschicht errechnen. Ist der Overhead unter einem Prozentsatz x, dann brauche ich mir über die Verbesserung der Zwischenschicht nicht mehr so viele Gedanken machen.
|
AW: Ado Performance steigern
Nee, wir sind vom Thema abgekommen. Die Auslassungen über BULK INSERT haben nichts mit den Performancemessungen zu tun.
|
AW: Ado Performance steigern
Bin von der Arbeit zurück..
Zitat:
MSSQL oder mein Kommentar im Eingangs-Thread waren ja nur der sportliche Ansporn mal etwas tiefer zu graben, sich mit ADO, wie es funktioniert und worauf es letztentlich BASIERT mal auseinander zu setzten, einen Code aufzusetzten um mal zu schauen, was da sooo geht. Und es geht einiges. Nochmal BULK, Provider, oder der gleichen sind hierbei außen vor die Zahlen sind im weitesten Sinne "Best-Case", wenn man so will, und für mich ein dringender Indikator für "Das kann so nicht stehen bleiben". Würde ich es so akzeptieren, hieße es den Kofferraum zu öffnen und zu schauen, wie viel Heu zu den anderen Türen reinschieben kann, ohne mir um gewisse veränderte oder veränderbare Umstände Gedanken zu machen. Mir ist mir die Kluft einfach zu groß. In dem besagten Handbuch finde ich keine gelisteten Properties der Objekte, mehr noch der Autor verweist immer wieder darauf, das er in all seinen Jahren bei MS, nie geänderte Props. gesehen hat. Er rät sogar davon ab, diese zu verändern. Kein Kommentar weshalb.. Einfach in den Raum gestellt. Was aber nicht heißen soll, das man es nicht macht :-D Darum wiederhole ich die Frage an den Fundus der DP: Was kann man tun? Hat jemand Erfahrungen mit veränderten Einstellungen von ADO? Kann man das Default Verhalten von ADO in irgend einer Weise *push*en? Michael P.s: Noch schlimmer wird es erst beim lesen der Daten, wenn man sich ![]() Edit und alle sub-links wie: ![]() 2. Edit: Bernhard, das "clonen" des insert Stmts und die gleichzeitige Ausführung des mehrfach Inserts habe ich vorher auch schon getestet. Abgesehen davon, das es möglicher Weise nicht von allen Ole-Anbietern unterstützt wird, hat es mit ADO eigentlich keine spürbaren Erfolge gebracht. Den Versuch habe ich auch wieder bei Seite gelegt. |
AW: Ado Performance steigern
Gesundes Neues!
Ich wollte das neue Jahr mal nutzen und das Thema anschieben. *Push, Push* Falls irgend jemand 'ne Ahnung hat?! Da mich das nicht in Ruhe gelassen hat, habe ich mal in ein paar freien Tagen ein neues Zeos-Protokol "OleDB" geschrieben. Nativer Zugriff via OleDB COM-Objects auf MSSQL(derzeit). Vollständig ohne ADO. Zeos-7.3 Siehe: ![]() Mal für euch zum Vergleich, was bei den Benchmark Tests (Beschreibung mit Resultaten(MSSQL fehlt da noch) ![]()
Code:
@Dejan
{
"Engine": "ZEOS MSSQL ADO-OLEDB", "CreateTableTime": "279.16ms", "NumberOfElements": 5000, "InsertTime": "862.34ms", "InsertRate": 5798, "InsertBatchTime": "598.49ms", "InsertBatchRate": 8354, "InsertTransactionTime": "456.03ms", "InsertTransactionRate": 10964, "InsertBatchTransactionTime": "146.33ms", "InsertBatchTransactionRate": 34168, "ReadOneByOneTime": "97.41s", "ReadOneByOneRate": 51, "ReadAllVirtualTime": "146.62ms", "ReadAllVirtualRate": 34100, "ReadAllDirectTime": "120.59ms", "ReadAllDirectRate": 41462, "ClientCloseTime": "7.29ms" } { "Engine": "ZEOS MSSQL OLEDB(SQLOLEDB)", "CreateTableTime": "22.25ms", "NumberOfElements": 5000, "InsertTime": "520.75ms", "InsertRate": 9601, "InsertBatchTime": "97.36ms", "InsertBatchRate": 51354, "InsertTransactionTime": "517.12ms", "InsertTransactionRate": 9668, "InsertBatchTransactionTime": "98.50ms", "InsertBatchTransactionRate": 50757, "ReadOneByOneTime": "713.98ms", "ReadOneByOneRate": 7002, "ReadAllVirtualTime": "30.65ms", "ReadAllVirtualRate": 163084, "ReadAllDirectTime": "18.63ms", "ReadAllDirectRate": 268326, "ClientCloseTime": "6.29ms" } { "Engine": "ZEOS MSSQL OLEDB(SQLNCLI11)", "CreateTableTime": "117.20ms", "NumberOfElements": 5000, "InsertTime": "545.12ms", "InsertRate": 9172, "InsertBatchTime": "93.04ms", "InsertBatchRate": 53738, "InsertTransactionTime": "549.59ms", "InsertTransactionRate": 9097, "InsertBatchTransactionTime": "94.09ms", "InsertBatchTransactionRate": 53135, "ReadOneByOneTime": "822.99ms", "ReadOneByOneRate": 6075, "ReadAllVirtualTime": "30.96ms", "ReadAllVirtualRate": 161451, "ReadAllDirectTime": "19.35ms", "ReadAllDirectRate": 258384, "ClientCloseTime": "6.59ms" } wenn ich mir das mal so anschaue, liegt MSSQL gar nicht so weit von FB entfernt mit den Insert-Raten. Scheint mir eher ein ADO-Problem zu sein.. Oder ich stell mich dusselig an.. Ich habe die Anzahl der Records auch mal auf 100.000 erhöht, doch der rechnerische Durchschitt bleibt so ziehmlich der Gleiche. :shock: @all Also ich würde mich freuen, wenn ich ADO noch ein wenig anschubsen könnten. Das kann doch wirklich nicht alles sein :twisted: Grüße, Michael |
Alle Zeitangaben in WEZ +1. Es ist jetzt 13:09 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-2025 by Thomas Breitkreuz