2011-05-31 7 views
1

J'ai 30 000 lignes dans une base de données qui doivent être vérifiés de similarité (en utilisant similar_text ou une autre telle fonction). Pour ce faire, il faudra effectuer 30 000^2 vérifications pour chaque colonne. Pour cela, il faudra effectuer 30 000^2 vérifications pour chaque colonne.Haute performance PHP simaliraty vérification sur grande base de données

J'estime que je vais vérifier en moyenne 4 colonnes.

Cela signifie que je devrai faire 3 600 000 000 chèques. Quel est le meilleur moyen (le plus rapide et le plus fiable) de faire cela avec PHP, en gardant à l'esprit les limites de mémoire et les délais, etc?

Le serveur doit toujours servir les pages Web en même temps.

PS. Le serveur que nous utilisons est un bélier Xeon 32 Go à 8 cœurs.

Edit:

La taille de chaque colonne est normalement inférieure à 50 caractères.

Répondre

1

Je suppose que vous avez juste besoin d'une recherche FULL TEXT.

Si cela ne vous convient pas, vous n'avez qu'une seule chance de résoudre ce problème: Cachez les résultats. Vous n'aurez pas à analyser 3bil des dossiers pour chaque demande

Quoi qu'il en soit, voici comment vous pouvez le faire:

$result = array();  

    $sql = "SELECT * FROM TABLE"; 
    while($row = ...) { 
     $result[] = $row; //> Append the current record  
    } 

résultats contient maintenant toutes les lignes de votre table.

A ce stade, vous avez indiqué que vous souhaitez similar_text() toutes les colonnes les unes avec les autres.
Pour faire cela et mettre en cache les résultats, vous avez besoin d'au moins une table (comme je l'ai dit dans le commentaire).

//> Starting calculating the similarity 
    foreach($result as $k=>$v) { 
     foreach($result as $k2=>$v2) { 

      //> At this point you have 2 rows, $v and $v2 containing your column 

      $similarity = 0; 

      $similartiy += levensthein($v['column1'],$v2['column1']); 
      $similartiy += levensthein($v['column2'],$v2['column2']);    
      //> What ever comparison you need here between columns 

      //> Now you can finally store the result by inserting in a table the $similarity 
      "INSERT DELAYED INTO similarity (value) VALUES ('$similarity')"; 

     }      
    } 

2 choses que vous devez remarquer:

  • je levensthein parce qu'il est beaucoup plus rapide que similar_text (notez sa valeur, il est au contraire de similar_text, parce que plus la valeur levensthein renvoie la moins l'affinité entre les chaînes)

  • I Utilisé INSERT RETARDÉ pour réduire considérablement le coût de la base de données

+1

Je ne cherche pas vraiment, j'ai besoin de voir si 1 colonne de données est plus de 90% similaire à toute autre colonne de données. – Petah

+0

Avez-vous besoin de comparer chaque colonne avec tout le reste? Ou vous avez seulement 1 chaîne de 1 colonne que vous devez comparer avec les autres? – dynamic

+1

La colonne de chaque ligne est comparée à la colonne de chaque autre ligne. – Petah

0

... similar_text() est O (n^3)!

avez-vous vraiment besoin d'un pourcentage de similarité pour chaque comparaison ou pouvez-vous faire une comparaison rapide du premier/milieu/dernier X octets des chaînes pour réduire le champ? Si vous cherchez simplement des dups, dites-vous ... vous pouvez probablement réduire le nombre de comparaisons que vous devez faire, et ce sera le point le plus efficace.

Questions connexes