最近处理了一个需求,找出数据中的所有生僻字,数据约1000万条,每条大约20多个字,结果文件500M。生僻字的判断标准是二级字库(600多个字)外的所有字都算生僻字。
最开始的想法很简单,两个循环:每条记录,针对二级字库中的每个字替换一次,输出结果。Powershell 脚本做这个操作So easy,跑起来之后,告知需求方第二天拿结果(1000万*6000的循环,想想也知道要跑很久)、
然后到了第二天,这个处理还没结束,由于没有输出进度,所以无法判断处理的进度(但到中午的时候仍然在跑)。
想想这个循环量确实太大,于是换了个姿势,将所有要处理的数据合并,直接用这个合并的结果去逐个替换那6000个二级字,这样只循环6000多次,而且随时替换后的数据起来越少,这处理速度应该越来越快。按照这个想法跑起来之后,发现仍然比较悲剧,一个小时之后速度没有明显增加。
最后不折腾了,玩数据库的,不是扔回数据库处理吧,将所有的数据以单字的形式扔回数据表,做 DISTINCT,然后做个NOT INT搞定。这回姿势很帅,处理时间只花了几分钟。
附相关脚本:
# 文件编码转换(Powershell)
$f, $ft = "$pwd\a.txt", "$pwd\aa.txt"
$ec, $ect = [Text.Encoding]::default, [Text.Encoding]::Unicode
[IO.File]::WriteAllLines($ft, [IO.File]::ReadAllLines($f,$ec), $ect )
# 将文件中的数据以单字形式扔到 SQL Server所需要的 bcp.fmt 文件
12.0
1
1 SQLNCHAR 0 2 "" 1 ch ""
-- SQL Server 读取文件,并得到 DISTINCT 的单字结果
SELECT DISTINCT ch INTO tb
FROM OPENROWSET(
BULK 'C:\aa.txt',
FORMATFILE = 'C:\bcp.fmt'
) T
【本文在个人微信公共号ZJCXC上同步发表】