同一段视频 9 种压法:设得越「清楚」,文件反而越大
同一段 63 秒视频 9 种压法实测:设得越清楚,文件越大画质没变好。

一句话结论:我最后没换。站上这点内容量,最笨的写法就已经够快;真要换,中文有两个坑——其中一个会悄悄搜不到东西,还不报错。
站上的搜索框一次搜三张表:文章、资源、工具。
现在的写法是把关键词前后各加一个百分号,让数据库挨行去看谁含有这几个字:
like = f"%{kw}%" # 搜「打包」,就变成 %打包%
搜「打包」,数据库就一行行翻,谁含有这两个字就留下。用起来没问题,但它用不上数据库的「目录」,每次搜索都要把每篇文章从头到尾读一遍。内容越多越慢。
我想知道两件事:要不要换成数据库自带的全文搜索?换了之后中文会不会出问题?
站上只有 1.7 万字,拿它比快慢等于在噪音里比速度。我改用自己电脑里的 207 个中文 markdown 文件,一共 98 万字,四种做法各建一个库,同一批词各跑 30 次,取中间那次耗时。
| 做法 | 搜「搜索」 | 搜「签名」 | 搜「验证码」 | 搜「重打包」 | 耗时 | 库变大到 |
|---|---|---|---|---|---|---|
| 现在的写法 | 38 条 | 15 条 | 17 条 | 3 条 | 3 毫秒 | 1.4 MB |
| 全文搜索(自带切词) | 10 条 | 9 条 | 8 条 | 1 条 | 0.02 毫秒 | 3.7 MB |
| 全文搜索(自己切词) | 36 条 | 15 条 | 17 条 | 3 条 | 0.04 毫秒 | 5.6 MB |
| 全文搜索(三字一组) | 0 条 | 0 条 | 17 条 | 3 条 | 0.03 毫秒 | 7.4 MB |
库的大小是压缩收拾过之后量的。三个结果都不在预料里。
一、数据库自带的切词方式,会把整段中文当成一个词。
全文搜索得先把文章切成一个个「词」,再建一份清单,跟书后面的人名索引一个道理。它默认认为:连续出现的字母和数字算一个词。汉字也被算作字母数字,于是一整段中文就变成了一个大词。
我翻了它建出来的词表,最长的一条有 33 个字,就是一句话:「腾讯微信openclaw插件api通信过程剖析与python原生代码复刻原理」。里面带「搜索」那条,是「支持关键词精确搜索和多关键词组合查询」这一整句。
所以搜「搜索」时,只有「这两个字正好被别的字符隔开、单独成词」的文章才找得到,命中数从 38 条掉到 10 条。
二、三字一组的切法能救短句,但两个字以内直接返回 0 条。
换个切法:每 3 个字符建一条清单项。这样「验证码」「重打包」这种 3 个字以上的词,结果和现在的写法一样,耗时只要 0.03 毫秒。
但两个字的词,比如「搜索」「签名」,它一条都不返回,也不报错。用户看到的不是错误提示,而是「本站没有相关内容」。中文里最常用的就是两个字、三个字的词。
三、自己切词,建清单和查清单两边都得改。
既然自带的不切,那就自己切:只在汉字上按两个字一组切开,灌进清单。
第一版我只改了灌进去的那边,结果搜「搜索」36 条(接近 38)、搜「签名」15 条(一样),但搜「验证码」0 条、搜「重打包」0 条。原因是查询时送进去的还是完整的一个词,而清单里已经没有这个词了。
把搜索词也按同样规则切开之后才对上:验证码 17 条、重打包 3 条,与现在的写法逐条一致。
if kw_ft and len(kw) >= 3: # 切好词、3 个字以上
rows = q("SELECT rowid FROM docs WHERE docs MATCH ?", (f'"{kw_ft}"',))
else: # 两个字、一个字,走老的写法
rows = q("SELECT id FROM docs WHERE body LIKE ?", (f'%{kw}%',))
同一段 63 秒视频 9 种压法实测:设得越清楚,文件越大画质没变好。
同一张壁纸 674.9 KB 能压到 122.9 KB,站上 15 张配图省到四分之一
三个老推送接口都死了,我用 IndexNow 把新文章推给搜索引擎