MySQL と PHP のレーベンシュタイン: 最適化されたアプローチ
元のコード スニペットでは、レーベンシュタイン距離は、指定された単語と各単語の間で計算されます。 PHP の levenshtein 関数を使用してデータベースから用語を取得します。ただし、このアプローチには複数のデータベース クエリが含まれるため、大規模なデータセットの場合は非効率的になる可能性があります。より効率的な解決策は、レーベンシュタイン距離をデータベース クエリ自体内のフィルターとして利用することです。
これを実現するには、MySQL に実装されたレーベンシュタイン関数が必要です。たとえば、次のカスタム関数を検討できます:
DELIMITER $$ CREATE FUNCTION levenshtein(s1 VARCHAR(255), s2 VARCHAR(255)) RETURNS INT BEGIN DECLARE len1 INT DEFAULT LENGTH(s1); DECLARE len2 INT DEFAULT LENGTH(s2); DECLARE i, j, cost, d INT DEFAULT 0; DECLARE sp VARCHAR(255); IF len1 = 0 THEN RETURN len2; ELSEIF len2 = 0 THEN RETURN len1; ELSE SET sp = REPEAT(' ', len1); FOR i = 1 TO len1 DO SET sp = CONCAT(sp, i); END FOR; SET sp = CONCAT(sp, CHAR(10)); FOR j = 1 TO len2 DO SET sp = CONCAT(sp, j, CHAR(10)); SET cost = j; FOR i = 1 TO len1 DO IF s1 SUBSTRING(i, 1) = s2 SUBSTRING(j, 1) THEN SET d = 0; ELSE SET d = 1; END IF; SET cost = LEAST( cost + 1, i + 1 + 1, j + d + 1 ); SET sp = CONCAT(sp, cost); END FOR; END FOR; SET sp = CONCAT(sp, CHAR(10)); RETURN SUBSTRING_INDEX(sp, CHAR(10), -1) - len1 - 1; END IF; END$$ DELIMITER ;
MySQL で Levenshtein 関数が定義されたら、クエリを次のように変更できます:
$word = mysql_real_escape_string($word); mysql_qery("SELECT `term` FROM `words` WHERE levenshtein('$word', `term`) BETWEEN 0 AND 4");
このクエリは次のように返されます。指定した単語までのレーベンシュタイン距離が 0 ~ 4 である単語テーブルのすべての単語。複数の PHP ループを回避し、データベースの組み込み関数に依存することで、特に大規模なデータセットのパフォーマンスを大幅に向上させることができます。
以上がPHP アプリケーションと MySQL データベース間のレーベンシュタイン距離計算を最適化するにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。