Ankündigung

Einklappen
Keine Ankündigung bisher.

[Erledigt] SQL zweistufige Abfrage

Einklappen

Neue Werbung 2019

Einklappen
X
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • [Erledigt] SQL zweistufige Abfrage

    Hallo,

    hänge gerade an einem Problem in SQL und finde dazu leider keine Antworten. Würde mich freuen wenn mir hier jemand weiterhelfen kann.

    Es geht prinzipiell um ein Laufzeit-Problem. Ich mache aus bestimmten Gründen, (ist ein anderes Thema), eine SQL-Abfrage die etwa so aussieht:

    Code:
    SELECT DISTINCT Wert FROM Tabelle WHERE (LEFT(Wort , 2)= "ab" OR LEFT(Wort , 1)= "c" 
    OR LEFT(Wort , 4)= "cdef" OR LEFT(Wort , 3)= "acd" ...

    Meine Datenbanken umfasst 100.000 Zeilen.
    Je nachdem können das ziemlich viele "OR" 's werden und das führt zu sehr langen Ladezeiten.

    Die Idee: Ich möchte die möglichen Zeilen vorher eingrenzen und aufbauend darauf den oben genannte Query anweden.

    Frage: Wie mache ich das?

    So klappt es nämlich nicht:

    Code:
    SELECT DISTINCT Wert FROM Tabelle WHERE (ID = 1) AND ((LEFT(Wort , 2)= "ab" OR LEFT(Wort , 1)= "c" 
    OR LEFT(Wort , 4)= "cdef" OR LEFT(Wort , 3)= "acd" ...
    So müsste SQL ja die Suche nur auf einem Element durchfühen nämlich dem mit der ID 1. Die Laufzeit verändert sich aber zum oben genannten Fall nicht.

    Hat jemand eine Idee?

  • #2
    Wenn da kein Index genutzt wird bringt das nix.

    Kommentar


    • #3
      Hallo, danke für die Antwort!

      Ich habe gelesen, dass ein Index das ganze beschleunigt und habe daraufhin einen Index auf die entsprechende Spalte angelegt.

      Aber wie kann ich von vornherein Ergebnisse eingrenzen auf denen ich dann als neue Grundlage meine Suche durchführe?

      Kommentar


      • #4
        Den größten gemeinsamen Nenner deiner Abfrage ermitteln und darauf "vorselektieren". Ich versteh allerdings den Sinn deiner Abfrage nicht, kann dir daher bei der Suche danach nicht weiterhelfen.

        Abgesehen davon: Wenn du komplexe Operationen auf Zelleninhalte abfeuerst, scheint deine Datenbank nicht normalisiert zu sein, Stichwort ACID, Atomarer Wertebereich.
        "[URL="http://www.youtube.com/watch?v=yMAa_t9k2VA&feature=youtu.be&t=25s"]Mein Name ist Lohse, ich kaufe hier ein.[/URL]"

        Kommentar


        • #5
          Und genau das ist meine Frage, wie kann ich "vorselektieren"?

          Kommentar


          • #6
            Hoffnungslos, du hörst nicht zu.
            "[URL="http://www.youtube.com/watch?v=yMAa_t9k2VA&feature=youtu.be&t=25s"]Mein Name ist Lohse, ich kaufe hier ein.[/URL]"

            Kommentar


            • #7
              Zitat von Elefterios Beitrag anzeigen
              H
              Ich habe gelesen, dass ein Index das ganze beschleunigt und habe daraufhin einen Index auf die entsprechende Spalte angelegt.
              Auf welche Spalte? Auf "wort"? Dann musst du mit "wort LIKE 'xxx%'" Abfragen. Mit LEFT(wort...) kann der Index nicht genutzt werden.

              Zitat von Elefterios Beitrag anzeigen
              Aber wie kann ich von vornherein Ergebnisse eingrenzen auf denen ich dann als neue Grundlage meine Suche durchführe?
              Mit einem Subquery, aber das bringt nix. Mysql optimiert die Abfragen selbstständig. Wenn es was zu optimieren gibt dann wird das in der Regel auch optimiert.

              Z.B. deine "Eingrenzung" oben bringt gar nix solang da kein Index drauf ist. Ist da ein Index drauf erkennt das Mysql und weiß das nur diese Datensätze weiter beachtet werden müssen. Ist kein Index drauf muss Mysql jeden Datensatz prüfen ob die Bedingung zutrift, wieso sollte dabei nicht auch gleich der Rest geprüft werden? Macht in dem Kontext wenig Sinn erst nach der ersten Bedingung zu filtern, das Ergebnis zu speichern und diese Ergebnis dann nochmals zu filtern.

              Zitat von Chriz Beitrag anzeigen
              Abgesehen davon: Wenn du komplexe Operationen auf Zelleninhalte abfeuerst, scheint deine Datenbank nicht normalisiert zu sein, Stichwort ACID, Atomarer Wertebereich.
              Falsches Stichwort. ACID beschreibt das Verhalten der Datenbank und nicht wie man Daten in einer Relationalen Datenbank strukturiert.

              Kommentar


              • #8
                @erc:
                Und wie soll das "Vorselektieren" mit LIKE funktionieren, wenn er völlig unterschiedliche Operationen vornimmt?

                Mit ACID hast du Recht.
                "[URL="http://www.youtube.com/watch?v=yMAa_t9k2VA&feature=youtu.be&t=25s"]Mein Name ist Lohse, ich kaufe hier ein.[/URL]"

                Kommentar


                • #9
                  Zitat von Chriz Beitrag anzeigen
                  @erc:
                  Und wie soll das "Vorselektieren" mit LIKE funktionieren, wenn er völlig unterschiedliche Operationen vornimmt?
                  Da ging es um den Index und nicht um das Vorselektieren. Ein Index wird mit LEFT(...) ausgehebelt, mit LIKE nicht (jedenfalls mit LIKE 'xxx%').

                  Kommentar


                  • #10
                    Danke für die Antwort!
                    Habe jetzt das ganze mit LIKE gelöst und eines FULLTEXT Index auf die entsprechende Spalte gesetzt. Ladezeit ist aber gefühlt gleich.

                    Kommentar


                    • #11
                      Zitat von Elefterios Beitrag anzeigen
                      Danke für die Antwort!
                      Habe jetzt das ganze mit LIKE gelöst und eines FULLTEXT Index auf die entsprechende Spalte gesetzt. Ladezeit ist aber gefühlt gleich.
                      Da muss wenn schon ein normaler Index drauf. Der Volltext Index wird nur mit match ... against genutzt.

                      Kommentar


                      • #12
                        Das hatte ich probiert, dann kam aber die Meldung:

                        Code:
                        BLOB/TEXT column 'Wort' used in key specification without a key length
                        Das Problem haben auch schon andere gehabt, habe lange gesucht aber bin nicht wirklich schlau geworden?

                        Kommentar


                        • #13
                          Habs hinbekommen, einfach die Länge in Klammern hinter den Splatennamen.
                          Jetzt läuft es flüssig, vielen Dank!

                          Kommentar

                          Lädt...
                          X