Announcement

Collapse
No announcement yet.

SQL Cursor Performance

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

  • SQL Cursor Performance

    Hallo zusammen,

    ich habe eine T-SQL Prozedur (MSSQL 2008), in welcher ein Cursor mit FAST-FORWARD und Read Only-Option eine große Tabelle (mit Index) durchläuft, dabei sehr einfache Rechenoperationen durchführt und die Ergebnisse anschließend in eine andere Tabelle schreibt. Jedoch dauert das ganze sehr lange. Das seltsame dabei: Auf dem DB-Server deuten keine mit Perfmon beobachteten Werte auf einen Flaschenhals hin; die CPU-Auslastung ist nur bei 10% (!), es gibt keine Locks etc. Festplatte langweilt sich ebenfalls.

    Wie in der Literatur nachzulesen ist, sei das bei Verwendung des Cursors normal.

    Meine Frage ist nun: Wieso ist der Cursor so langsam, wenn der Server doch allem Anschein nach genügend Power hätte, den Cursor schneller abzuarbeiten?

    Der Ausführungsplan sagt mir, dass 46% der Zeit für "Clustered Index Insert" und 45% der Zeit fürs Sortieren der Select-Anweisung in der Cursordeklaration drauf gehen.

    Schon mal danke für die Hilfe!
    Christoph

  • #2
    Wieso ist der Cursor so langsam, wenn der Server doch allem Anschein nach genügend Power hätte, den Cursor schneller abzuarbeiten?
    Das kann viele Gründe haben. CPU ist nur ein Faktor. IO Waits wäre z.B. ein anderer.

    Davon abgesehen: Musst Du wirklich einen Cursor verwenden? Wenn es nur einfache mathematische Operationen sind (und auch komplexere) lassen sich diese ohne weiteres per SQL erledigen:

    Code:
    INSERT INTO ziel SELECT ... FROM quelle
    Ob es deine Operation als SQL Befehl gibt kannst Du in der Doku nachlesen. Die Grundrechenarten, Wurzelziehel, Potenzieren, Runden etc. sind auf jeden Fall dabei.

    Schneller als jeder Cursor, denn ein Cursor bedeutet immer Einzelsatzverarbeitung.

    Dim
    Zitat Tom Kyte:
    I have a simple philosophy when it comes to the Oracle Database: you can treat it as a black box and just stick data into it, or you can understand how it works and exploit it as a powerful computing environment.

    Comment


    • #3
      Mein Aktivitätsmonitor sagt mir, dass die Wartekategorie "Other" ca. 99% der Ressourcenwartevorgänge meiner Abfrage ausmachen. Buffer I/O und Network I/O dagegen nur minimal Zeit beanspruchen.

      Ich will zusätzlich eine recht komplizierte Berechnungsprozedur ausführen, bei der jeweils zwei aufeinander folgende Zeilen benötigt werden, wofür der Cursor aufgrund seiner Funktionsweise eigentlich prädestiniert ist. Da der Cursor aber anscheinend rechnerunabhängig sehr langsam arbeitet, würde mich interessieren, wie der Cursor bei der Berechnung grundsätzlich vorgeht und wo der Engpass liegt. Was bedeutet denn in dem Zusammenhang Einzelsatzverarbeitung?

      Ich werde es nun auch mit einer While-Schleife versuchen, in der Hoffnung, eine bessere Performance zu erzielen.

      Comment


      • #4
        bei der jeweils zwei aufeinander folgende Zeilen benötigt werden,
        Auch dafür benötigt man keinen Cursor sondern die analytischen Funktionen lead bzw. lag.
        In der Doku zum SQL Server findest Du mehr zu deren Verwendung.

        Was bedeutet denn in dem Zusammenhang Einzelsatzverarbeitung?
        Eine Zeile lesen, verarbeiten, schreiben. Nächste Zeile lesen, verarbeiten, schreiben. Das ist Einzelsatzverarbeitung. Wohingegen SQL mengenorientiert arbeitet. Alle Zeilen lesen, verarbeiten und in einem Rutsch schreiben. Das ist in etwa so, als ob Du einen Berg Erde mit einer Schaufel oder mit einem Schubkarren von A nach B fährst. Die Menge bleibt gleich aber Du musst mit der Schaufel viel öfter hin und her gehen und verlierst dadurch natürlich Zeit.

        Dim
        Zitat Tom Kyte:
        I have a simple philosophy when it comes to the Oracle Database: you can treat it as a black box and just stick data into it, or you can understand how it works and exploit it as a powerful computing environment.

        Comment


        • #5
          Originally posted by dimitri View Post
          Auch dafür benötigt man keinen Cursor sondern die analytischen Funktionen lead bzw. lag.
          In der Doku zum SQL Server findest Du mehr zu deren Verwendung.
          Ein paar analytische Funktionen wie ROW_NUMBER sind ab 2005 implementiert,
          allerdings nicht die Funktionen LEAD und LAG (auch nicht in 2008 und 2008 R2)

          um dem abzuhelfen, stimme man bei microsoft.connect dem folgenden zu:


          In irgendwas muss ja auch Oracle mal besser sein

          Comment

          Working...
          X