我有两个数据文件。第一个是一个转储文件,它非常巨大(超过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秒,所以如果算上50公里的搜索,大约需要17天,这是不可接受的,因为我必须每隔几天运行一次。
所以问题是,我如何才能在几个小时内更有效地实现这个结果。目前我正在我的笔记本电脑上测试这个,但我有一台台式电脑,我可以在上面安装一个服务器版本的Linux,它可以用来运行这个任务。该任务最重要的特征是什么(处理器速度、核心数量、内存)?
欢迎提出任何建议。
您可以尝试以下方法:
步骤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并尝试更改,更改后您可以根据需要更改这些变量。
因此,在您的初始操作之后,您有一个由唯一字符串组成的大文件和一个由50k个搜索字符串组成的文件(我认为这些字符串也是唯一的)。
你可以对它们进行排序并寻找重复:
sort serach_strings data | uniq -d
查看MATCH()
。如果您的表有全文索引,并且您也将模式加载到另一个表中,则可以尝试以下操作:
SELECT pattern, COUNT(*)
FROM data, patterns
WHERE MATCH(name) AGAINST (pattern);
我将首先在patterns
表中只运行10行左右的行来测试它。