Announcement

Collapse
No announcement yet.

MS SQL Server über ADO oder ODBC?

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • MS SQL Server über ADO oder ODBC?

    Hallo,

    man liest überall, dass ADO schneller ist als ODBC. Bei Zugriff auf MSSQL Server ergeben alle unsere Tests das Gegenteil. Das Ausführen einer Abfrage über TQuery ist mit BDE/ODBC dreimal schneller als über ADO/OLEDB Provider. Bei den ADO-Komponenten ist ServerCursor, ForwardOnly Cursor und ReadOnly Zugriff eingestellt, das müsste doch den schnellstmöglichen Zugriff ergeben?

    Kann mir jemand sagen, wie man für SQL Server ADO schneller macht als BDE/ODBC, oder kann jemand unsere Testergebnisse bestätigen?

    Gruß,

    Robert Weck

  • #2
    Hallo,

    die Frage ist nicht so sehr <i>ODBC oder ADO</i>, sondern mehr <i>ADO Express oder Native ADO-Objekte</i>, wie der folgende Vergleich zeigt:

    Aufgabe 1: 1000 Datensätze über eine Stored Procedure in eine
    SQL Server 7-Datenbank einfügen:<br>
    a) BDE SQL Links = 1560 ms<br>
    b) ADO Express (Borland) = 5780 ms<br>
    c) ADO-Objekte (Microsoft) = 1010 ms <br>

    Aufgabe 2: 1000 Datensätze über eine Stored Procedure in eine
    SQL Server 7-Datenbank einfügen, wobei alle Aufrufe
    in eine explizite Transaktion gekapselt werden.<br>
    a) BDE SQL Links = 450 ms<br>
    b) BDE ODBC = 1050 ms<br>
    c) ADO Express = 1100 ms<br>
    d) ADO-Objekte = 530 ms<br>

    Aufgabe 3: 1000 Datensätze aus der Datenbank abrufen:<br>
    a) BDE SQL-Links (TStoredProc) = 450 ms<br>
    b) BDE ODBC (TQuery) = 1060 ms<br>
    c) ADO Express (TADOStoredProc) = 1100 ms<br>
    d) ADO Express (TADOCommand) = 1100 ms<br>
    e) ADO (Connection/Command) = 540 ms<br>

    &gt;Bei den ADO-Komponenten ist ServerCursor, ForwardOnly Cursor und ReadOnly Zugriff eingestellt, <br>
    &gt;das müsste doch den schnellstmöglichen Zugriff ergeben?

    Immer dann, wenn mehrere Datensätze zur gleichen Zeit abgerufen werden sollen (aber die Anzahl moderat ist), hat <b>clUseClient</b> den Vorteil, dass implizit der <i>Firehouse</i>-Cursor verwendet wird <b>und</b> OLE DB/ADO/TCPIP die maximale Transport-Kapazität ausnutzt. Man bekommt einen sehr kurzer Peak voller Netz- und CPU-Last, wobei im Gegensatz dazu bei clUseServer das Fetchen jedes einzelnen Datensatzes (Ping-Pong-Spiel zwischen Client und MS SQL Server) über das Netzwerk Zeit kostet.

    Der folgende Vergleich stammt aus meinem ADO-Buch:

    <i>Wird das Programm nun jeweils für clUseServer und clUseClient getestet, ergibt sich das folgende Bild bei der CPU-Auslastung: Einer kurzen Spitze bei clUseServer steht sehr breiter Block mit Vollauslastung bei clUseClient gegenüber. Beachten Sie dabei unbedingt, dass sich der Arbeitsanteil bei clUseClient aus dem Transport (Firehouse-Cursor) und der lokalen Datenverarbeitung zusammensetzt. Die folgende Tabelle fasst die Ausführungszeiten in Windows-Ticks zusammen, die beim Laden und Durchblättern der 42 898 Datensätze der SQL Server 2000-Datenbank (die auf einem externen Server liegt und über ein LAN angesprochen wird). Beachten Sie, dass das Öffnen und Laden der 42 898 Datensätze bei clUseClient dank dem von ADO angeforderten sehr schnellen Firehouse-Curors nur 861 Ticks benötigt. Somit ist das Durchblättern des clientseitigen RecordSets in der Schleife für die langandauernde hohe CPU-Auslastung verantwortlich. Bei clUseClient spielt auch CacheSize keine Rolle, da ein Firehouse-Cursor immer den schnellsten Weg verwendet. </i>
    <pre>
    CursorLocation CursorType CacheSize Zeitbedarf in Windows-Ticks
    -------------- ---------- --------- ---------------------------
    clUseServer ctOpenForwardOnly 1 4166
    clUseServer ctOpenForwardOnly 100 3856
    clUseClient ctStatic 1 85673
    clUseClient ctStatic 1 861 (nur Öffnen, Loop inaktiv)
    </pre>
    Wichtiger als der Zeitvergleich ist die Tatsache, dass Microsoft in der <b>MDAC Road Map</b> die ODBC-Treiber als Auslaufmodell bezeichnet: Der <i>Microsoft OLE DB Provider for ODBC Driver (MSDASQL)</i> taucht in der Liste der auslaufenden Bestandteile auf.
    &#10

    Comment


    • #3
      Hi Andreas,
      <br>
      <br>Welche anderen ADO Komponenten kann man denn statt ADO-Express(Borland) empfehlen, damit man ADO-Objekt / BDE Geschwindigkeit erreicht?
      <br>
      <br>Was mich oben drein noch an ADO-Express stört:
      <br>Es fehlt so eine Art "Refresh SQL" wie bei IBX. Wenn man mit ADO-<br>Express ein refresh SQL erstellen will, so muß man das über den Quellcode machen. Ich finde das VCL Konzept eigentlich genial (das ist auch der Grund warum ich nicht gerne ADO-Object benutze) und weiß nicht warum man sowas nicht auch am Objekt verankern kann. Gibt es keine Komponente für Delphi 5 Enterprise, die so etwas bietet? (Ich glaube bei Delphi6 ist es nich besser, oder?)
      <br>(ich hoffe ja, das diese Fargen auch in deinem neuen Buch beantwortet werden)
      <br>
      <br>Danke!
      <br>
      <br>mfg
      <br>P

      Comment


      • #4
        Hallo,

        &gt;Welche anderen ADO Komponenten kann man denn statt ADO-Express(Borland) empfehlen..

        keine - statt dessen würde ich direkt auf die nativen ADO-Objekte (COM-Objekte von Microsoft zurückgreifen). Erst dann, wenn die Benutzeroberfläche (TDBGrid, TDBEdit) ins Spiel kommen soll, kann man das Ergebnis an TADODataSet übergeben. Das folgende Beispiel demonstriert diesen Fall. Zuerst erledigen die nativen ADO-Objekte die Arbeit, und wenn das Ergebnis feststeht, wird ADO Express angebunden:
        <pre>
        procedure TForm1.ButtonADOdbGoClick(Sender: TObject);
        var
        aConnection : _Connection;
        aCommand : _Command;
        aParam : _Parameter;
        aRS : _RecordSet;
        vRowsAffected: OleVariant;
        iReturnValue : Integer;
        iError : Integer;
        sError : String;
        iCol,iRow : Integer;
        begin
        aConnection := CoConnection.Create;
        with aConnection do
        begin
        CursorLocation := adUseClient;
        Open(ADOConnection1.ConnectionString,'', '', adConnectUnspecified);
        end;
        try
        aCommand := CoCommand.Create;
        try
        with aCommand do
        begin
        CommandType := adCmdStoredProc;
        Set_CommandText('spSPTestEx');
        Set_ActiveConnection(aConnection);
        // Rückgabewert
        aParam := CreateParameter('RETURN_VALUE', adInteger,
        adParamReturnValue,4, EmptyParam);
        Parameters.Append(aParam);
        // Input-Parameter
        aParam := CreateParameter('@sWert', adVarChar,
        adParamInput, 10, EmptyParam);
        Parameters.Append(aParam);
        Parameters[1].Value := 'Command';
        // Recordset-Objektinstanz für die SP-Datenmenge
        aRS := CoRecordset.Create;
        aRS.Set_ActiveConnection(aConnection);
        aRS.CursorLocation := adUseClient;
        // Command-Objekt ausführen, Ergebnisse abholen
        aRS.Open(aCommand, EmptyParam, adUseClient,
        adLockBatchOptimistic, adOptionUnspecified);
        // Fehler aufgetreten?
        with aConnection do
        if Errors.Count > 0 then
        begin
        for iError := 0 to Errors.Count - 1 do
        sError := sError + Errors[iError].Description + #10#13;
        ShowMessage(sError);
        end;

        aRS.Set_ActiveConnection(nil);
        // ADO Express anbinden -> Daten über TDataSource im TDBGrid anzeigen
        ADODataSet2.Recordset := aRS;
        ADODataSet2.Active := True;

        StatusBar1.SimpleText := IntToStr(vRowsAffected);
        end;
        finally
        aCommand := nil;
        end;
        finally
        aConnection.Close;
        aConnection := nil;
        end;
        end;
        </pre>
        Über den Aufruf:
        <pre>
        ADODataSet2.Recordset := aRS;
        ADODataSet2.Active := True;
        </pre>
        wird ADO Express die bereits aktive Ergebnismenge in Form der Recordset-Objektinstanz untergeschoben

        Comment


        • #5
          Hallo,
          ich hab die Aufgabe bekommen, direkt über OLE DB auf eine SQL Datenbank zuzugreifen. Im MS Visual Studio geht das ja gut über die OLE DB Consumer Templates. Gibt es sowas in Delphi auch und ist das überhaupt ratsam? Über OLE DB direkt müsste ja eigentlich der schnellste Zugriff möglich sein, oder nicht

          Comment


          • #6
            Hallo,

            &gt;Über OLE DB direkt müsste ja eigentlich der schnellste Zugriff möglich sein, oder nicht

            unter Windows ist das Hantieren mit dem OLE DB-API in der Tat sehr schnell, aber unter .NET sind die nativen Zugriffe über die Klassen aus dem Namespace <i>System.Data.SqlClient</i> noch schneller.

            Normalerweise greifen Anwendungsentwickler nur über ADO auf OLE DB zu, denn OLE DB ist vom Tippaufwand mit Assembler zu vergleichen (wer schreibt heute schon freiwillig ein Windows-Programm nur in Assembler?). Im Platform SDK hat Microsoft "zur Abschreckung" das Tool <b>Microsoft OLE DB Rowset Viewer</b> beilegt, mit dem man einen Blick unter die Motorhaube werfen kann, indem alle ausgelösten OLE DB-Aufrufe mitprotokolliert werden. Selbst für einfachste Datenbankfunktionen kommen da hunderte Zeilen zusammen.

            Lange Rede kurzer Sinn: Nur Entwickler von neuen Treibern (OLE DB Providern) sollten sich OLE DB direkt antun, alle anderen sind mit ADO besser bedient

            Comment


            • #7
              Hi,
              <br>
              <br>unter #1 wurden BDE,ADOExpress und ADO Objekte verglichen. Wo kann man denn da ungefähr TBetterAdoDataSet einordnen (wohl gemerkt bei einem Zugriff auf SQL Server 7)?
              <br>
              <br>Danke!
              <br>
              <br>mfg
              <br>P

              Comment


              • #8
                Hallo,

                die FreeWare-Komponente TBetterAdoDataSet zielt primär auf den Zugriff auf ACCESS-Datenbanken (MDB), wobei die Komponente nur ein Nachfahre von TADODataSet ist, der die von Borland "vergessenen" Sachen nachholt. An dem generellen Performance-Unterschieden ändert auch TBetterAdoDataSet nichts

                Comment

                Working...
                X