Ankündigung

Einklappen
Keine Ankündigung bisher.

[Erledigt] Schnelle Volltextsuche bei 2,5 Mio Einträgen

Einklappen

Neue Werbung 2019

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

  • [Erledigt] Schnelle Volltextsuche bei 2,5 Mio Einträgen

    Hallo zusammen,

    hat jemand eine Idee wie ich eine schnelle Volltextsuche bei über 2,5 Millionen Einträgen realisieren kann?
    Es geht um eine Ajax Basierte Autocomplete Suche die bislang ~4 Sek. braucht um einen String zu finden, und die Vorschlagsliste aktualisiert.
    Etwas beschleunigt habe ich das ganze indem ich erst ab dem 4. eingegebnen Zeichen suchen lasse.

    Bislang:
    4,3662 Sek.

    Code:
    SELECT DISTINCT spalte AS spalte FROM tabelle WHERE spalte LIKE '%string%' ORDER BY spalte ASC LIMIT 0,10
    Rennt wie Sau:
    0,0531 Sek.
    Code:
    SELECT DISTINCT spalte AS spalte FROM tabelle WHERE MATCH (spalte) AGAINST ('+string' IN BOOLEAN MODE) LIMIT 0,10
    Problem dabei:
    Die Vorschlagsliste wird bei der zweiten Abfrage erst bei genauen Wort Treffern geladen und ausgegeben. Das hilft dem User dann wenig.

    Jetzt meine Frage:
    Gibt es eine Möglichkeit die 1. Abfrage soweit zu optimieren das Sie gleichwertige Zeiten erzielt?
    Gibt es Möglichkeiten die Datenbank zu optimieren, das die 1. Abfrage besser arbeitet?

    Ich sag schonmal Danke.


  • #2
    Ein paar Fragen dazu:

    a) Wie sieht denn die Tabellenstruktur von "tabelle" aus. Bsw. was für ein Datentyp ist "spalte".

    b) Ist auf "spalte" ein Index?

    c) Wie sieht der EXPLAIN Deiner Abfrage aus:

    Code:
    EXPLAIN SELECT DISTINCT spalte AS spalte FROM tabelle WHERE spalte LIKE '%string%' ORDER BY spalte ASC LIMIT 0,10
    Das Ergebnis bitte gut formatiert oder als Bild hier zeigen.

    Grüße
    Thomas

    Kommentar


    • #3
      ..oder auch ein allgemeiner Vorschlag dazu. Ich setze mal voraus, dass sich die Texte nicht sehr häufig ändern.

      Die bisherige Tabelle:

      Code:
      CREATE TABLE texte (
       text_id INT NOT NULL,
       datum DATE NOT NULL,
       text VARCHAR(2000),   -- <= diese Spalte wird bisher durchsucht
       ..
       ..
       weitere spalten...
      )
      Die Spalte "texte" hat zum Beispiel folgenden Inhalt:
      "Dies ist ein langer Text .. ist ein langer Text .. ist ein lager Text"

      Diesen Text in Worte zerlegen und folgende zusätzliche Tabelle füllen.

      Code:
      CREATE TABLE worte (
       wort_id NOT NULL,
       text_id NOT NULL,
       wort VARCHAR(20) NOT NULL
      )
      Jedes Wort wird nur einmal in der Tabelle worte gespeichert

      "Dies"
      "ist"
      "ein"
      "langer"
      "Texte"

      Damit wird die Datenmenge viel kleiner und die Suche geht schneller.

      Code:
      SELECT text_id 
        FROM worte
        JOIN texte
          ON text_id = text_id
       WHERE wort LIKE '%suche%';
      Grüße
      Thomas

      Kommentar


      • #4
        zu. a) Tabelle: MyISAM - Spalte: varchar(255)
        zu. b) Noch kein Index angelegt.
        zu c)

        Kommentar


        • #5
          Zitat von thomas_w Beitrag anzeigen
          Damit wird die Datenmenge viel kleiner und die Suche geht schneller.

          Code:
          SELECT text_id 
            FROM worte
            JOIN texte
              ON text_id = text_id
           WHERE wort LIKE '%suche%';
          Grüße
          Thomas
          Guter Ansatz Thomas, aber es handelt sich bei der zu durchsuchenden Zeile um Maximal 4 bis 5 Wörter.

          Kommentar


          • #6
            Wenn kein Index auf spalte existiert, ist dass natürlich einen Versuch wert. Kostet natürlich einigen Speicherplatz. Wenn es nichts bringt, kann der Index jederzeit wieder entfernt werden ( DROP INDEX ... )

            Code:
            CREATE INDEX sx_tabelle_01 ON tabelle (spalte);
            Wie sieht jetzt der EXPLAIN aus..?

            Grüße
            Thomas

            Kommentar


            • #7
              Nach dem Index - >0,00157 Sek. Sprechen für sich.
              Jetzt muss ich leider etwas anders an die Sache herangehen, da ca. alle 3min Änderungen in der Tabelle vorgenommen werden und der Index jedes mal neu erstellt werden müsste. Werde eine Tabelle mit der zu durchsuchenden Spalte erstellen, und die Änderungen täglich aus der Haupttabelle via Cronjob aktuallisieren. Dann muss ich den Index täglich nur einmal erstellen.

              Danke Thomas

              Kommentar


              • #8
                Zitat von ratZar Beitrag anzeigen
                Nach dem Index - >0,00157 Sek. Sprechen für sich.
                Jetzt muss ich leider etwas anders an die Sache herangehen, da ca. alle 3min Änderungen in der Tabelle vorgenommen werden und der Index jedes mal neu erstellt werden müsste. Werde eine Tabelle mit der zu durchsuchenden Spalte erstellen, und die Änderungen täglich aus der Haupttabelle via Cronjob aktuallisieren. Dann muss ich den Index täglich nur einmal erstellen.
                MySQL verwaltet den Index selbst, wenn die entsprechende Spalte geändert wird, wird automatisch der Index von MySQL aktualisiert. Da ist kein zusätzliche Aufwand Deinerseits nötig.

                Grüße
                Thomas

                Kommentar


                • #9
                  Das stimmt, aber das erstellen dauert zwischen 1 und 2 Minuten. Der Server wäre also permanent damit beschäftigt den Index zu erneuern. Eine Aktualisierung täglich reicht aus.

                  Danke nochmal für die Hilfe! Bis dann!

                  Kommentar


                  • #10
                    Ich wüsste aber nicht dass du die automatische Aktualisierung deaktivieren kannst in MySQL! Außerdem wird bei einer Änderung ja nicht der komplette Index neu aufgebaut sondern nur das Element was geändert wurde im Index geändert. Es ist also kein wirklich großer Overhead der entsteht.

                    Kommentar


                    • #11
                      Ein volltext-Index auf der Spalte und eine Suche mit CONTAIN statt mit Jokern sollte auch einiges an Geschwindigkeit bringen.
                      sigpic

                      Kommentar

                      Lädt...
                      X