Announcement

Collapse
No announcement yet.

OR Operator verlangsamt Abfrage

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

  • OR Operator verlangsamt Abfrage

    ich sitze gerade an einer eigentlich leichten SQL-Abfrage in der ich in der WHERE-Klausel ein OR benutze.
    Die Abfrage läuft über 7min (dann habe ich sie abgebrochen)
    Abfrage sieht so aus:

    [highlight=sql]
    select * from Staffel
    where
    ( CAST(CAST(WARENGR.Firma AS nvarchar(8)) +'.'
    + CAST(WARENGR.Mandant AS nvarchar(8)) +'.'
    + CAST(ST_1 AS nvarchar(8)) +'.'
    + CAST(ST_2 AS nvarchar(8)) +'.'
    + CAST(ST_3 AS nvarchar(8)) +'.'
    + CAST(ST_4 AS nvarchar(8)) +'.'
    + CAST(ST_5 AS nvarchar(8)) +'.'
    + CAST(ST_6 AS nvarchar(8)) +'.'
    + CAST(ST_7 AS nvarchar(8)) +'.'
    + CAST(ST_8 AS nvarchar(8)) +'.'
    + CAST(ST_9 AS nvarchar(8)) +'.'
    + CAST(ST_10 AS nvarchar(8)) AS nvarchar(150))
    IN (
    select CAST(CAST(KUNDART.FIRMA AS nvarchar(8)) +'.'
    + CAST(KUNDART.MANDANT AS nvarchar(8)) +'.'
    + CAST(VK_AB_1 AS nvarchar(8)) +'.'
    + CAST(VK_AB_2 AS nvarchar(8)) +'.'
    + CAST(VK_AB_3 AS nvarchar(8)) +'.'
    + CAST(VK_AB_4 AS nvarchar(8)) +'.'
    + CAST(VK_AB_5 AS nvarchar(8)) +'.'
    + CAST(VK_AB_6 AS nvarchar(8)) +'.'
    + CAST(VK_AB_7 AS nvarchar(8)) +'.'
    + CAST(VK_AB_8 AS nvarchar(8)) +'.'
    + CAST(VK_AB_9 AS nvarchar(8)) +'.'
    + CAST(VK_AB_10 AS nvarchar(8)) AS nvarchar(150))
    from KundenVerknuepfung)
    OR
    CAST(CAST(WARENGR.Firma AS nvarchar(8)) +'.'
    + CAST(WARENGR.Mandant AS nvarchar(8)) +'.'
    + CAST(ST_1 AS nvarchar(8)) +'.'
    + CAST(ST_2 AS nvarchar(8)) +'.'
    + CAST(ST_3 AS nvarchar(8)) +'.'
    + CAST(ST_4 AS nvarchar(8)) +'.'
    + CAST(ST_5 AS nvarchar(8)) +'.'
    + CAST(ST_6 AS nvarchar(8)) +'.'
    + CAST(ST_7 AS nvarchar(8)) +'.'
    + CAST(ST_8 AS nvarchar(8)) +'.'
    + CAST(ST_9 AS nvarchar(8)) +'.'
    + CAST(ST_10 AS nvarchar(8)) AS nvarchar(150))
    IN (
    select CAST(CAST(ARTLASER.FIRMA AS nvarchar(8)) +'.'
    + CAST(ARTLASER.MANDANT AS nvarchar(8)) +'.'
    + CAST(ME_1 AS nvarchar(8)) +'.'
    + CAST(ME_2 AS nvarchar(8)) +'.'
    + CAST(ME_3 AS nvarchar(8)) +'.'
    + CAST(ME_4 AS nvarchar(8)) +'.'
    + CAST(ME_5 AS nvarchar(8)) +'.'
    + CAST(ME_6 AS nvarchar(8)) +'.'
    + CAST(ME_7 AS nvarchar(8)) +'.'
    + CAST(ME_8 AS nvarchar(8)) +'.'
    + CAST(ME_9 AS nvarchar(8)) +'.'
    + CAST(ME_10 AS nvarchar(8)) AS nvarchar(150))
    from LagerVerknuepfung)
    ) [/highlight]

    Ich weiß dass es viel Performance kostet zusammengesetzte Strings zu vergleichen aber wenn ich die Abfragen OHNE OR separat voneinander ausführe, dauern sie 2 Sekunden.

    -

    Kennt jemand einen alternative um dieses Problem zu lösen?
    Zuletzt editiert von Falk Prüfer; 02.07.2012, 16:21. Reason: Original Frage wiederhergestellt und formatiert

  • #2
    Ich kann das nicht lesen. Kannst Du das bitte vernünftig formatieren?

    [highlight=sql]<DeinStatement>[/highlight]

    Und vielleicht die Zeilen noch etwas einrücken, so dass man das ganze wirklich lesen kann.

    Danke!

    Comment


    • #3
      Ich kann nichts ändern -.- jedes mal bekomme ich folgenden Text angezeigt:
      IPS detected for "VULN SQL injection select from attempt -4/Web Attack"

      Comment


      • #4
        Ohne das Statement zu sehen -irgendwie ist der Eingangspost jetzt ganz durcheinander: Die Klammersetzung in der WHERE Klausel ist wahrscheinlich falsch, prüfe das mal.
        Ich habs gleich!
        ... sagte der Programmierer.

        Comment


        • #5
          *lach* Das ist ja schlau in einem Forum wo Code gepostet wird findet er eine SQL Injection Attacke *lach*

          Comment


          • #6
            Damit das hier kein Geisterthread wird, hab ich mal den originalen Post des TE wiederhergestellt und ein wenig Formatierung reingebracht.

            Anmerkung: Bei mir war nix mit SQL-Injection-Attacke...
            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


            • #7
              IPS detected for "VULN SQL injection select from attempt -4/Web Attack"
              Lies die Meldung mal komplett. Das ist höchstwahrscheinlich die Intrusion Detection bzw. Intrusion Prevention deines Routers.

              Comment


              • #8
                Danke Falk ich hab das auch schon versucht, aber ich muss mich mal tiefer mit der Forensoftware auseinander setzen.

                @Topic: Ich würde darauf tippen dass das IN recht inperformant ist. Warum vergleichst Du eigentlich nicht einfach die Felder? Das müsste doch aufs gleiche hinauslaufen und WESENTLICH performanter sein. Durch das trennen mit den Punkte vergleichst Du sowieso jedes Feld einfach mit dem anderen. Dann kannst Du das IN durch einen Join ersetzen und das Query wird bestimmt um einiges schneller. Sofern die Typen zusammen passen kannst Du Dir sogar den Cast nach NVARCHAR sparen. Auch das dürfte um einiges schneller gehen

                Comment


                • #9
                  Originally posted by semcor View Post
                  Ich weiß dass es viel Performance kostet zusammengesetzte Strings zu vergleichen aber wenn ich die Abfragen OHNE OR separat voneinander ausführe, dauern sie 2 Sekunden.

                  -

                  Kennt jemand einen alternative um dieses Problem zu lösen?
                  Abgesehn von dem Sinn dieser Casting Aktion, könntest du die Abfrage in 2 separate Abfragen unterteilen und mit einem Union All wieder zusammen führen und anschließend ein Distinct über die Ergebnismenge legen. Es könnte sein, dass Du damit den Schrott umgehst, der offensichtlich intern bei dieser Abfrage abläuft. Vielleicht reicht schon direkt ein UNION ohne ALL um dem Problem auszuweichen, dann kann man auf die DISTINCT Abfrage verzichten.

                  Ich vermute, dass die Zusammenführung der Ergebnismenge, die ja durch das OR stattfinden muss, "suboptimal" läuft. Jedenfalls liegt hier ein Unterschied zu Deinem 2 Sekundenexperiment.
                  Gruß, defo

                  Comment


                  • #10
                    Hallo,

                    so wie die Abfrage konstruiert ist, schreit es förmlich danach inperformant zu sein. Ein IN ist ja ansich schon eine riesige Kette von OR-Verknüpfungen und je nach Anzahl der Daten innerhalb der IN-Abfrage wird das entsprechend langsam, noch dazu wenn durch explizite Typumwandlung und Verkettung (der Sinn erschliesst sich mir zumindest überhaupt nicht) die Nutzung von Indizes nahezu unmöglich wird.

                    Wie schon mehrfach angesprochen, solltest du die Felder einfach direkt vergleichen. Entweder indem du das IN in ein EXISTS umformulierst oder das IN in der Form:
                    [highlight=sql]
                    ...
                    WHERE (WARENGR.Firma, WARENGR.Mandant, ...) IN (
                    SELECT KUNDART.FIRMA, KUNDART.MANDANT, ...
                    [/highlight]
                    verwendest.

                    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


                    • #11
                      Dann kann ich aber doch auch gleich einen JOIN machen oder? Das dürfte bestimmt noch etwas schneller gehen

                      Etwa sowas:

                      [highlight=sql]
                      SELECT *
                      FROM warengruppe warengr
                      JOIN kundenart kundart ON
                      warengr.Firma = kundart.Firma
                      warengr.Mandant = kundart.Mandant
                      ...
                      [/highlight]

                      Comment


                      • #12
                        Originally posted by Falk Prüfer View Post
                        Hallo,
                        Ein IN ist ja ansich schon eine riesige Kette von OR-Verknüpfungen ..
                        Gruß Falk
                        Logisch ist das sicher richtig, von der Implementierung her aber nicht unbedingt. Die Einzelmessungen a 2 Sekunden zeigen das m.E. auch. Natürlich muss der Algorithmus aufgrund der Abfragekonstruktion ohne einen einzigen Index auskommen, und es bleibt oberflächlich betrachtet nichts, als die Teilergebnisse intern zu sortieren.
                        Interessant finde ich, dass das OR in Kombination mit den anderen "Vorgaben" der Abfrage so sehr in die Knie geht. Was m.E. auf eine deutliche, interne Implementierungsschwäche hindeutet. Bei 2 Sekunden für die Einzelergebnisse kann das Volumen nicht besonders groß sein. Möglicherweise hat sich der Prozess auch schlicht aufgehängt bei der Abfrage. Die 7 Minuten sind also keine representative Laufzeit, sondern einfach Wartezeit. Dies müsste man an Logs oder Dumps auch nachvollziehen können. Im Sinne von Robustheit eines RDBMS auch ein interessanter Punkt.

                        Wie gesagt, auch mir erschließt sich der Sinn der Abfrageformulierung nicht, aber das muss er ja auch nicht. Es wurde nach Alternativen gefragt. Nett wäre natürlich, etwas über die Gründe zu erfahren.
                        Gruß, defo

                        Comment

                        Working...
                        X