Announcement

Collapse
No announcement yet.

SQL-Query mit Funktion extrem langsam

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

  • SQL-Query mit Funktion extrem langsam

    Hallo,

    ich bräuchte mal eure Hilfe, komme bei diesem Problem hier nicht weiter. Ich habe ein SQL-Statement, welches die Ausgabewerte auf einen bestimmten Datumsbereich eingrenzt. Einmal wird der Datumswert über eine Funktion abgefragt (der Normalfall) und einmal wird er direkt im SQL-Statement angegeben (zum Testen). Dabei ist mir aufgefallen, dass das Query mit der Funktion wesentlich länger (um den Faktor 15) braucht. Die Querys und die Ausführungspläne sehen dann wie folgt aus:

    SQL-Statement mit Funktion:
    Code:
    SELECT
      *
    FROM
      "DWH_CORE"."CO_F_IST_PERS"  "CO_F_IST_PERS"
      WHERE 
      (("CO_F_IST_PERS"."DWH_VALID_FROM" < dwh_app.pa_utilities.fu_get_appointed_date_start or "CO_F_IST_PERS"."DWH_VALID_TO" > dwh_app.pa_utilities.fu_get_appointed_date_end ) 
      or (("CO_F_IST_PERS"."DWH_VALID_FROM" between dwh_app.pa_utilities.fu_get_appointed_date_start and dwh_app.pa_utilities.fu_get_appointed_date_end) 
      and ("CO_F_IST_PERS"."DWH_VALID_TO" between dwh_app.pa_utilities.fu_get_appointed_date_start and dwh_app.pa_utilities.fu_get_appointed_date_end))) AND
      ( "CO_F_IST_PERS"."FACT_PERS_CST_FJ1" = 0 and "CO_F_IST_PERS"."FACT_PERS_CST_FJ2" = 0 and "CO_F_IST_PERS"."FACT_PERS_HRS_FJ1" = 0 and "CO_F_IST_PERS"."FACT_PERS_HRS_FJ2" = 0 )
    Dazugehöriger Ausführungsplan:


    Und folgend das gleiche ohne die Funktion, sondern mit direkter Angabe des Datums.
    SQL-Statement mit Datumsangabe:
    Code:
    SELECT
      *
    FROM
      "DWH_CORE"."CO_F_IST_PERS"  "CO_F_IST_PERS"
      WHERE 
      (("CO_F_IST_PERS"."DWH_VALID_FROM" < to_date('02.02.2010','DD.MM.YYYY') or "CO_F_IST_PERS"."DWH_VALID_TO" > to_date('02.02.2010','DD.MM.YYYY') ) 
      or (("CO_F_IST_PERS"."DWH_VALID_FROM" between to_date('02.02.2010','DD.MM.YYYY') and to_date('02.02.2010','DD.MM.YYYY')) 
      and ("CO_F_IST_PERS"."DWH_VALID_TO" between to_date('02.02.2010','DD.MM.YYYY') and to_date('02.02.2010','DD.MM.YYYY')))) AND
      ( "CO_F_IST_PERS"."FACT_PERS_CST_FJ1" = 0 and "CO_F_IST_PERS"."FACT_PERS_CST_FJ2" = 0 and "CO_F_IST_PERS"."FACT_PERS_HRS_FJ1" = 0 and "CO_F_IST_PERS"."FACT_PERS_HRS_FJ2" = 0 )
    Ausführungsplan:


    Wie man sieht, verändert sich der Ausführungsplan erheblich. Mit der Funktion werden die Indizes angesprochen und mit direkter Datumsangabe wird ein Full-Table-Scan ausgeführt, welcher in diesem Fall auch schneller ist.
    Nur wie kann ich den CBO nun "überzeugen" einen FTS durchzuführen und die Indizes außen vor zu lassen? Habe schon versucht Histogramme für die Tabelle zu erstellen, aber an den Zugriffswegen hat sich nichts geändert.
    Attached Files

  • #2
    Das der erste Select mit den Funktionen langsamer ist, rührt daher, dass für jeden Datensatz in der Tabelle beide Funktionen erneut aufgerufen werden müssen.

    Ich kenne die Funktionen zwar nicht, aber da Du keinen Parameter übergibst, denke ich mal sie selektieren einfach ein Datum aus einer Tabelle.
    Du solltest, meines erachtens, die Funktionen vor dem eigentlichen Select auszuführen dabei die Rückgabewerte in Variablen ablegen und diese Variablen dann im Select verwenden.

    Comment


    • #3
      Danke für deinen Beitrag. Ich hatte in der Zwischenzeit die beiden Funktionen in Variablen zwischengespeichert und es hatte sich nichts an der Performance getan, allerdings habe ich jetzt die Lösung. Sobald ich alle Date-Felder noch "trunce" trunc() ist die Abfrage schnell.

      Comment

      Working...
      X