我有两个数据文件。第一个是转储文件,它非常庞大(超过6Gb)并包含数据库中的记录。第二个是字符串列表(每行一个字符串)我必须在另一个文件的行中找到部分匹配(大约50k行)。到目前为止,我对bash中的第一个文件进行了一些操作。我已经将第一个字段(其中包含有用的信息)打印到一个新文件,而不是删除前25行,其中只包含注释和生成的字符串,然后我做了一个独特的排序(因为可能存在重复,所以需要唯一的第一个字段值,我认为按字母排序可能会加快搜索速度。在我的笔记本电脑上生成它需要大约半小时。最后,文件每行包含一个字符串,大约有10 ^ 8行。
awk '{print $1}' dump > first
sed '1,25d' first > temp_data
sort -u temp_data > data
现在我必须从较大的文件中找到较小文件中所有字符串的部分匹配(或至少是它们的计数)。首先,我认为我将使用bash执行此操作并运行以下代码:
awk 'FNR==NR{a[$1]; next} {s=$1; for (i in a) if (index(i, $1)) s=s FS i; if (s!=$1) print s}' serach_strings data > result
但看起来它会永远运行所以我决定尝试将文件加载到mysql中(加载较大的文件需要大约半小时)并尝试运行几个测试字符串:
SELECT COUNT(*) FROM data WHERE name LIKE '%teststring%';
这需要大约30秒,所以如果我计算50k搜索需要大约17天这是不可接受的,因为我必须每隔几天运行这整个事情。
所以问题是如何在几个小时内更有效地实现这一结果。目前我正在我的笔记本电脑上测试这个,但我有一台台式电脑,我可以在其上安装一个服务器版Linux,可以用来运行这个任务。该任务最重要的特征是什么(处理器速度,核心数量,内存)?
欢迎任何建议。
答案 0 :(得分:1)
所以,在你最初的操作之后,你有一个大的独特字符串文件和一个50k搜索字符串的文件(我假设它们也是唯一的)。
您可以对它们进行排序并查找重复项:
sort serach_strings data | uniq -d
答案 1 :(得分:1)
您可以尝试以下方法:
步骤1:如果您使用的是mysql版本5.6,那么您可以将数据表保留为innodb或myisam,但如果您使用的是较低版本,请将表格保留为myisam。
步骤2:在要搜索字符串的列上创建全文索引。
步骤3:创建一个存储过程,它将所有字符串保存在第二个表中的游标中,并从数据表中逐个搜索并在任何表中存储计数,要么可以在第二个表中针对各种字符串进行更新,要么可以插入任何新表。
答案中的补充:
如果您共享表大小,表架构,服务器配置,那么我可以帮助您。您还可以尝试以下 -
创建全文索引的命令:
ALTER TABLE mytable ADD FULLTEXT(mycoloumn);
如果您在更改表格时遇到问题,则可以更改以下变量:
tmp_table_size = 1G
max_heap_table_size = 1G
max_allowed_packet = 64M
key_buffer_size = 50M
innodb_buffer_pool_size = half of your RAM
注意:为此,您的机器中有足够的RAM。
更改它们后重新启动mysql并尝试更改并在更改后可以根据您的要求更改这些变量。
答案 2 :(得分:1)
查看MATCH()
。如果您的表具有全文索引,并且您将模式加载到另一个表中,则可以尝试以下操作:
SELECT pattern, COUNT(*)
FROM data, patterns
WHERE MATCH(name) AGAINST (pattern);
我会首先在patterns
表中只用10行左右来测试它。