2012-04-05 10 views
1

Ich habe eine Tabelle mit 8 Millionen Zeilen, die gegen eine riesige Liste von Badwords gescannt werden muss.beste Abfrage, um eine große MySQL-Datenbank (Zeilen) gegen eine Badword-Liste zu aktualisieren

Meine erste Idee war:

UPDATE `master` SET `blacklisted`='1' WHERE MATCH (`content-desc`, `content-title`) AGAINST (' 
badword1 | badword2 | badword3 | "and many more"' IN BOOLEAN MODE) 

leider diese Version einige Worte vergessen und war nicht Groß- und Kleinschreibung!

nächster Versuch war zu

$badwords = array("badword1","badword2","badword3","and-many-more"); 

foreach($badwords AS $name) 
    { 
     $sql = "UPDATE `master` SET `blacklisted`='1' WHERE concat(`content-title(mediumtext)`,`content-desc(mediumtext)`) LIKE '%".$name."%'"; 

     sleep(6); 

// Could limit this query by 100.000 and adding another foreach loop help? 
// How would the foreach look like (select count(*) from master?)/100.000 

    } 

vielen Anfragen, die meinen Server sofort getötet! Vielleicht könnte die kommentierte Idee helfen ?! (aber howto?)

Wer hat die beste Idee, wie Sie diese Abfrage lösen, ohne den mysql-Server zu sehr zu stressen? Vielen Dank!

+1

Die erste sollte unempfindlich Fall gewesen wäre. Welche Sortierung verwenden Sie? Verwenden Sie auch nicht '|' für 'oder'. "Oder" ist [impliziert] (http://dev.mysql.com/doc/refman/5.5/en/fulltext-boolean.html), verwende einfach Leerzeichen. –

Antwort

1

Nicht sicher, wie dies für Ihre Tabelle funktioniert, aber Sie können einen Vergleich zwischen Groß- und Kleinschreibung vornehmen, als Teil einer Join-Klausel.

Also, Sie haben eine Tabelle, die Sie scannen möchten (mit 8 m Zeilen)

CREATE TABLE IF NOT EXISTS haystack ( word varchar (10) NOT NULL ) ENGINE = InnoDB STANDARD charset = UTF-8 ;

- Dumping Daten für Tabelle haystack

INSERT INTO haystack (word) VALUES ('eine Katze'), ('category'), ('Katze'), ('decatur'), ('Hund'), ('Taube'), ('eagle'), ('a beagle'), ('CAT'), ('CAT');

und ein Tisch mit Schimpfwörter

CREATE TABLE IF NOT EXISTS needles ( bad_word varchar (10) NOT NULL ) ENGINE = InnoDB STANDARD charset = UTF-8;

- Dumping Daten für Tabelle needles

INSERT INTO needles (bad_word) -Werten ('Katze'), ('Eagle');

Die folgende Abfrage wird die beiden Tabellen fallweise mit Fuzzy-Abgleich verknüpfen.

SELECT * FROM Heuhaufen AS h JOIN Nadeln AS n ON h.Word COLLATE utf8_general_ci LIKE CONCAT ('%', n.bad_word, '%');

Sie können natürlich ein Update über die Ergebnisse leicht genug durchführen. Hier sind die Ergebnisse, die ich bekommen habe ... Wenn Sie Wörter wie "Dickson", "Stitsville", "Annehmen" nicht ausschließen wollen, wird es viel schwieriger.

Wort bad_word

eine Katze Katze ist

Kategorie Katze

Katze Katze

decatur Katze

Adler Adler

ein beag le Adler

Katze Katze

CAT Katze

+0

Der Trick, case-insensitiv zu machen, ist in dem Vergleich, der den Join antreibt, die Spezifikation der COLLATION (COLLATE utf8_general_ci), bei der es sich um eine Groß-/Kleinschreibung ohne UF8-Version handelt. Es gibt ähnliche Kollatierungen für lateinische Zeichensätze, wenn Sie das verwenden. – rogodeter

Verwandte Themen