Announcement

Collapse
No announcement yet.

Frage zu SQL Abfrage

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

  • Frage zu SQL Abfrage

    Hallo Zusammen,

    ich teste derzeit eine neue Applikation im Testsystem auf Performance und mir ist im SQL Profiler eine Abfrage aufgefallen, die mir ist ein bisschen Schwierigkeiten macht.

    Genaugesagt ist es eine gespeicherte Prozedur, die einige Parameter aufnimmt und selbst dann eigene SQL Funktionen aufruft.

    Ich versuche das mal vereinfacht darzustellen und konzentriere mich auf das
    SQL Statement was von der gespeicherten Prozedur aufgerufen wird.

    Dieses sieht etwa so aus:

    Code:
    SELECT   DISTINCT TAB1.KATEGORIE,
                        dbo.xyz_FN_Funktion1(TAB1.WERT1, TAB1.WERT2, TAB1.WERT3, TAB1.WERT4) AS AA,
                        dbo.xyz_FN_Funktion2(@Param1,@Param2) as BB,
                        @Param1 as Param1,
                        dbo.xyz_FN_Funktion3(@Param1,@Param2) as CC,
                        dbo.xyz_FN_Funktion4(@Param1,@Param2) as DD,
                        dbo.xyz_FN_Funktion5(@Param1,@Param2) as DD,
                        TAB2.WERT3
          FROM         TAB1
                INNER JOIN
                          TAB2 ON TAB1.CODE = TAB2.CODE 
          WHERE     (TAB1.WERT1 = @Param1) AND (TAB1.WERT2 = @Param2) AND (TAB1.WERT3 = @Param3)                      
          ORDER BY TAB1.KATEGORIE
    im SELECT Statement werden also 5 SQL Funktionen aufgerufen, die irgendwas zurückgeben.
    Mein Problem ist jetzt das ich im SQL Profiler sehe, dass hierbei ohne Reads verursacht werden und dieses SQL Statement oben sehr sehr oft aufgerufen wird, nämlich genau so viel mal wie es Zeilen gibt die durch die WHERE Klausel eingeschlossen werden MAL die Anzahl der Funktionen im SQL Statement enthalten, sind also 5.

    Beispiel:

    Die WHERE Klausel
    WHERE (TAB1.WERT1 = @Param1) AND (TAB1.WERT2 = @Param2) AND (TAB1.WERT3 = @Param3)

    liefert 1000 Zeilen, im SELECT sind 5 Funktionen = 5x 1000 Zeilen.

    Nehme ich beispielsweise eine SQL Funktion raus, verringert sich das ganze sofort auf 4x 1000 Zeilen usw...

    Eigentlich sollte das Statement aber nur so oft aufgerufen wird, wieviele einmalige (DISTINCT) Kategorieren es gibt.

    Ich nehme mal an durch die SQL Funktionen funzt das DISTINCT nicht mehr?

    Gibt es irgendwie eine Möglichkeit die SQL Funktionen auch nur so oft ausführen zu lassen, wieviele einmalige Kategorieren es gibt?

    Von den 1000 Zeilen die die durch die WHERE Klausel erfasst werden, sind max. 10 unterschiedliche Kategorien vorhanden.

    Ich bin nicht der Programmierer, aber mich würde es sehr interessieren, ob es vielleicht eine Möglichkeit, dies performanter zu gestalten.

    Ich hoffe ich konnte das halbwegs verständlich zur späten Stunde erläutern.

    Danke und Gruß
    Pierre

  • #2
    Hallo Pierre,
    Ich nehme mal an durch die SQL Funktionen funzt das DISTINCT nicht mehr?
    Das betrachtest Du von der falschen Seite. Logischer Weise müssen die Funktionen erst ausgeführt werden, da von deren Ergebnissen wiederum das Ergebnis des Distincts abhängt.

    Also, den ersten Funktionsaufruf (xyz_FN_Funktion1) sehe ich noch ein, der wird mit Werten aus der Tabelle1 ausgeführt und kann entsprechend je Datensatz ein individuelles Ergebnis liefern, aber
    dbo.xyz_FN_Funktion2(@Param1,@Param2) as BB,
    wird immer mit Konstanten ausgeführt und da Funktionen deterministisch sind, liefern sie immer das gleiche Ergebnis. Von daher reicht es eigentlich, die Funktionen einmalig aufzurufen und mit den konstanten Ergebnissen weiter zu arbeiten.
    Olaf Helper

    <Blog> <Xing>
    * cogito ergo sum * errare humanum est * quote erat demonstrandum *
    Wenn ich denke, ist das ein Fehler und das beweise ich täglich

    Comment


    • #3
      Hallo,
      Originally posted by O. Helper View Post
      ...und da Funktionen deterministisch sind, liefern sie immer das gleiche Ergebnis. Von daher reicht es eigentlich, die Funktionen einmalig aufzurufen und mit den konstanten Ergebnissen weiter zu arbeiten.
      Wo ist festgelegt das Funktionen IMMER deterministisch sind? Wenn die Funktion z.B. einen Parameter mit einer neu erzeugten UUID oder dem aktuellen Timestamp verknüpft, dann ist sie nicht mehr deterministisch!


      Originally posted by PierreChanab View Post
      ...Ich nehme mal an durch die SQL Funktionen funzt das DISTINCT nicht mehr?

      Gibt es irgendwie eine Möglichkeit die SQL Funktionen auch nur so oft ausführen zu lassen, wieviele einmalige Kategorieren es gibt?
      Doch, dass DISTINCT funktioniert schon, aber in der von O. Helper beschriebenen Art und Weise.
      Wenn die Funktionen für das DISTINCT keine Rolle spielen, also tatsächlich deterministisch sind, dann könntest du in einer View (oder Subquery) zuerst die relevanten Daten mittels Distinct ermitteln und erst in einer Abfrage auf diese View (oder Subquery) die Funktionen anwenden.

      Gruß Falk
      Wenn du denkst du hast alle Bugs gefunden, dann ist das ein Bug in deiner Denksoftware.

      Quellcode ohne ein Mindestmaß an Formatierung sehe ich mir nicht an! Ich leiste keinen Privatsupport per Mail oder PN!

      Comment


      • #4
        Vielen Dank für eure Antworten.
        Ich habe mir das eben noch mal im Profiler angesehen und leider habe ich gestern Abend in meinem Modell eine Sache bei den Funktionen vergessen.

        Funktion1 ist soweit richtig, bei den Funktionen2-5 werden noch weitere nicht identische Parameter übergeben.

        dbo.xyz_FN_Funktion2(@Param1,@Param2,'konstanterWe rt1') as CC,
        dbo.xyz_FN_Funktion3(@Param1,@Param2,'konstanterWe rt2') as DD,

        usw.

        Funktion2-5 sind aber exaxt identisch (ist immer die gleiche Funktion), nur der Aufruf unterscheidet sich durch den konstanten Wert.

        Der Rückgabewert ist dadurch immer unterschiedlich.

        In meinem Beispiel sieht es so aus, dass Funktion 2-5 unterschiedlich sind, aber in "real" ist es die gleiche Funktion.


        Wenn die Funktionen für das DISTINCT keine Rolle spielen, also tatsächlich deterministisch sind, dann könntest du in einer View (oder Subquery) zuerst die relevanten Daten mittels Distinct ermitteln und erst in einer Abfrage auf diese View (oder Subquery) die Funktionen anwenden.
        Hast du vielleicht ein kleines Beispiel (Prinzip) für mich? Dann würde ich das sehr gerne testen.

        Gruß
        Pierre
        Zuletzt editiert von PierreChanab; 17.02.2010, 10:45.

        Comment


        • #5
          Originally posted by PierreChanab View Post
          ...Hast du vielleicht ein kleines Beispiel (Prinzip) für mich? Dann würde ich das sehr gerne testen.
          Statt:
          [highlight=sql]
          select distinct function_a(tab1.feld1) res1
          from tabelle tab1
          where tab1.feld2 = 'irgendwas'
          [/highlight]
          könnte man
          [highlight=sql]
          select function_a(sub1.feld1) res1
          from (
          select distinct tab1.feld1
          from tabelle tab1
          where tab1.feld2 = 'irgendwas') sub1
          [/highlight]
          verwenden, wenn function_a deterministisch ist, also für jeden Aufruf mit identischem Parameter exakt denselben Wert liefert.
          Damit wird die Funktion function_a nur noch für die bereits zusammengefassten Werte aufgerufen.

          Gruß Falk
          Wenn du denkst du hast alle Bugs gefunden, dann ist das ein Bug in deiner Denksoftware.

          Quellcode ohne ein Mindestmaß an Formatierung sehe ich mir nicht an! Ich leiste keinen Privatsupport per Mail oder PN!

          Comment


          • #6
            Hallo Falk,

            danke für das Beispiel anhand einer deterministischen Funktion.

            Bei mir ist es leider nur so, dass es immer uterschiedliche Parameter und unterschiedliche Rückgabewerte gibt.
            In meinem 1. Post habe ich das noch nicht richtig dargestellt gehabt.

            Viele Grüße
            Pierre

            Comment


            • #7
              Hallo Pierre,
              Originally posted by PierreChanab View Post
              ...Bei mir ist es leider nur so, dass es immer uterschiedliche Parameter und unterschiedliche Rückgabewerte gibt.
              das heißt ja nicht das die Funktion deshalb nicht deterministisch ist. Sie kann für unterschiedliche Parameter durchaus unterschiedliche Ergebnisse liefern Deterministisch heißt nur das sie bei unterschiedlichen (zeitlich versetzten) Aufrufen mit identischen Parametern immer diesselben Ergebnisse liefern muß. Von der Seite sind eben fast alle Funktionen deterministisch, es sei denn sie verwenden selbst wiederum nichtdeterministische Funktionen (z.B. RAND oder UUID) oder beziehen sich auf veränderliche Daten (Datum, Zeit, etc.)

              Gruß Falk
              Wenn du denkst du hast alle Bugs gefunden, dann ist das ein Bug in deiner Denksoftware.

              Quellcode ohne ein Mindestmaß an Formatierung sehe ich mir nicht an! Ich leiste keinen Privatsupport per Mail oder PN!

              Comment


              • #8
                Hallo Falk,

                tausend Dank ich habe es mit Subqueries wie du es vorhin beschrieben hast, tatsächlich um ein tausendfaches optimieren können.

                Ihr seit echt gut :O).

                Ich teste jetzt mal fleißig weiter, nicht das doch noch irgendwo der Wurm drin ist

                Gruß
                Pierre.

                Comment

                Working...
                X