如何加速Python实现MySQL两表(一对多)字符串相似度对比?
优化字符串相似度对比的性能方案
核心问题
你的代码采用双重逐行循环,9万×9.5万=8.55亿次计算量,单条耗时1分钟完全不具备可行性,必须从算法、工具、执行方式三个维度优化。
1. 改用批量匹配替代双重循环
thefuzz的process.extract/process.extractOne是底层优化过的批量匹配方法,比手动写循环效率高一个数量级,直接针对单条字符串批量匹配全表目标字符串。
示例代码:
from thefuzz import fuzz, process import mysql.connector # 数据库连接 mydb = mysql.connector.connect( host="localhost", user="root", password="", database="db_test" ) cursor = mydb.cursor() # 只查询需要对比的字符串列(替换成你实际用的列名,对应原代码row[1]) cursor.execute("SELECT target_column FROM table1") table1_strings = [row[0] for row in cursor.fetchall()] cursor.execute("SELECT target_column FROM table2") table2_strings = [row[0] for row in cursor.fetchall()] # 批量匹配每个table1字符串在table2中的最相似结果 for s in table1_strings: # score_cutoff设置相似度阈值,过滤低匹配结果 result = process.extractOne(s, table2_strings, scorer=fuzz.ratio, score_cutoff=70) if result: match_str, similarity = result[0], result[1] print(f"原字符串: {s}, 匹配结果: {match_str}, 相似度: {similarity}")
2. 切换到RapidFuzz加速
thefuzz是rapidfuzz的Python封装,直接使用rapidfuzz可以获得3-10倍的速度提升,API完全兼容。
先安装:
pip install rapidfuzz
替换导入即可,代码逻辑不变:
from rapidfuzz import fuzz, process
3. 并行处理榨干CPU资源
利用多进程并行处理table1的字符串,充分利用多核CPU性能,适合大规模数据场景。
示例代码:
from rapidfuzz import fuzz, process import mysql.connector from concurrent.futures import ProcessPoolExecutor # 定义单条字符串匹配函数 def match_single_string(s): result = process.extractOne(s, table2_strings, scorer=fuzz.ratio, score_cutoff=70) return (s, result) if result else (s, None) # 数据库查询部分同上,先获取table1_strings和table2_strings # 并行处理,max_workers设为CPU核心数 with ProcessPoolExecutor(max_workers=4) as executor: all_results = list(executor.map(match_single_string, table1_strings)) # 输出结果 for s, res in all_results: if res: print(f"{s} -> 匹配: {res[0]}, 相似度: {res[1]}")
4. 减少不必要的数据开销
- 不要用
SELECT *,只查询需要对比的字符串列,减少内存占用和数据传输量; - 在数据库层面提前清洗字符串(比如转小写、去除特殊字符),降低计算复杂度:
SELECT LOWER(REPLACE(target_column, ' ', '')) FROM table1;
内容的提问来源于stack exchange,提问作者Dhileep
相关产品推荐
相关产品推荐

