为何windows自带的文件搜索这么慢,而Everything的这么快?
首先感谢Everything的作者,将这么好的软件免费开放。致敬。
由于该软件不是开源软件,下面提到的方案都是根据公开资料整理的。
这事儿其实分成两个阶段,Everything v1.5 之前和 v1.5 之后。v1.5之前只能检索文件名。v1.5之后可以对文件内容进行检索。
先讲 v1.5 之前,那个只搜文件名的阶段。为什么快,四个原因。
首先,数据来源不同。
Windows 搜索找文件是递归遍历目录树,调用 FindFirstFile、FindNextFile 这类 API,一个文件夹接一个文件夹地枚举。文件数量越大,耗时线性增长,这是 O(n) 的复杂度。(我是没搞懂微软的大神们为啥一定要这么搞)
Everything 不碰目录树。它直接读取 NTFS 文件系统的 MFT,也就是主文件表。MFT 是 NTFS 分区自己维护的一个元数据库,卷上所有文件和文件夹的基本信息(文件名、路径、大小、修改时间)都记录在里面,结构是固定格式的。Everything 启动时一次性解析 MFT,拿到全盘文件清单。百万级文件的 MFT 也就几十 MB,几秒钟读完,不需要逐个访问文件。这一步直接绕过了目录遍历,把 O(n) 变成了接近 O(1) 的结构化读取。
第二,索引存储位置不同。
Windows 搜索用的是 ESE 数据库(可扩展存储引擎),索引维度非常多(文件内容、邮件、OneDrive、系统设置、图片 EXIF 等等),索引库体积动辄几个 GB 甚至更大,做不到全量加载到内存。查询的时候必然要读磁盘,磁盘 IO 的延迟比内存访问高几个数量级。而且效果也不咋地,反正搜邮件的时候我都绝望了。
Everything 的索引只存文件名、完整路径、文件大小、时间戳等等。所有匹配都在内存里完成,没有磁盘读写参与。查询延迟压到 10 毫秒以下。
第三,索引更新机制不同。
Windows 搜索靠一个后台服务(WSearch),用低优先级进程在系统空闲时扫描文件变更。文件新增、改名之后,可能要等几分钟才能被搜到,有时候索引卡住了就永远搜不到。
Everything 监听 NTFS 的 USN Journal,也就是更新序列号日志。这是 NTFS 文件系统自带的功能,每次文件的创建、删除、修改、改名都会被实时写入这个日志。Everything 持续读取 USN Journal,文件变动的毫秒级内就能更新内存索引,不需要重新扫描磁盘,始终是实时的。
第四,访问路径不同。
Windows 搜索作为系统组件,必须遵守完整的权限控制流程。每个文件的访问都要经过 ACL 权限校验,还要兼容 FAT32、exFAT、网络共享等各种文件系统,处理多用户隔离、UAC 限制、系统文件保护等。API 调用链路很长,层层封装带来大量额外开销。
Everything 以管理员或 SYSTEM 权限运行,直接调用 DeviceIoControl 访问原始卷(比如 \\.\C:),绕过了 Windows Shell API 和文件系统权限校验的全部封装,直接读取 NTFS 底层结构。代价就是只支持 NTFS 和 ReFS 文件系统。
少一道历史兼容性,果然能省很多事。
然后就是v1.5 之后的阶段。
Everything 1.5 加入了文件内容检索功能,但还是比 Windows 搜索快很多。目前看主要是这三点优化:
第一,内容索引的范围控制。
Everything 1.5 的内容索引默认是关闭的,需要用户手动开启,而且可以精确配置索引范围:指定只索引哪个分区、只索引哪些文件类型(比如只索引 .docx、.txt、.py)、只索引小于特定大小的文件、甚至只索引符合文件名规则的文件。用户可以把索引范围控制得很小,索引体积依然能全部加载到内存。全文检索同样在内存里完成,实测百万文件库的全文检索平均响应不到 1 秒。
第二,检索引擎的架构。
Everything 1.5 内置了多格式解析器,不依赖系统 Filter Host(但也可以调用系统 iFilter 作为备选),减少了进程间通信环节。全文索引采用倒排索引结构,支持内存映射。更关键的是,全文索引和原有的文件名索引是联动的:用户可以先用文件名、路径、大小、修改时间把范围缩小到几十个文件,再在这些文件里搜内容。Windows 搜索则是全文检索直接命中整个索引库,两者实际扫描的文件数量可能差几千倍。
第三,资源调度策略。
Everything 在执行用户查询时会主动分配 CPU 和内存资源,查询任务优先完成。(后台内容索引也支持用户自定义调度策略,比如只在系统空闲时更新、限制索引速度,不会和前台操作抢资源。)
最后说一句本质上的区别。
微软的优势和历史惯性就是:统统支持,全面兼容。
这么一搞难度蹭蹭蹭就上来了。
这时候谁还顾得上性能。
Everything 的设计目标非常单一:让用户以最快速度精准定位文件。
还有个能对文件内容进行检索的软件,叫anytxt,体验也很好。不过高级功能要付费。建议付费使用。
但依然有个痛点没有解决,就是exchange邮箱里的邮件检索。