用巨大的文件(80GB)来加快速度吗?


113
 grep -i -A 5 -B 5 'db_pd.Clients'  eightygigsfile.sql

它已经在相当强大的linux服务器上运行了一个小时,否则该服务器不会过载。grep可以替代吗?关于我的语法的任何可以改进的地方(例如,egrep,fgrep更好吗?)

该文件实际上位于与挂载共享到另一个服务器的目录中,但是实际的磁盘空间是本地的,因此应该没有什么区别?

grep占用了93%的CPU


8
根据您的语言环境,-i开关可能会减慢该过程,请尝试不使用-i或使用LC_ALL=C grep ...。另外,如果您只是在寻找固定的字符串,请使用grep -F
雷神

5
作为@dogbane提到使用LC_ALL = C沿可变fgrep一样可以加快你的search.I做了一些测试,并能实现1400%的性能提升,并写了一个详细的文章,为什么这是我的加快grep的岗位
JacobN

我很好奇-80GB的文件大小是多少?我想认为,当文件变大时,可能会有更好的存储策略(例如旋转日志文件,或按层次结构分类到不同的文件和文件夹中)。同样,如果更改仅发生在文件的某些位置(例如末尾),则只需存储前一节中未更改的某些grep结果即可,而不是grep原始文件,而是grep存储的结果文件。
Sridhar Sarnobat

我选择了github.com/google/codesearch-索引编制和搜索都快如闪电(用Go语言编写)。cindex .索引当前文件夹,然后按csearch db_pd.Clients
ccpizza

1
如果您的文件被索引或排序,则可以大大提高速度。根据定义,搜索每一行都是O(n),而可以通过将文件二等分来查找已排序的文件-此时,您需要花费一秒钟的时间来搜索80gb(因此,为什么80gb索引的数据库根本不需要时间进行简单的SELECT,而您的grep需要...好,只要它需要)。
查尔斯·达菲

Answers:


148

以下是一些选择:

1)给您的grep命令加上前缀,LC_ALL=C以使用C语言环境而不是UTF-8。

2)使用fgrep是因为您要搜索固定的字符串,而不是正则表达式。

3)删除该-i选项(如果不需要)。

因此,您的命令将变为:

LC_ALL=C fgrep -A 5 -B 5 'db_pd.Clients' eightygigsfile.sql

如果将文件复制到RAM磁盘,速度也会更快。


5
多谢了一个数量级。顺便说一句,我加了-n以获取行号。也可能是-m在比赛后退出
zzapper 2012年

5
哇,非常感谢@dogbane很棒的提示!这使我走下了一条研究隧道,以了解为什么LC_ALL = C加快了grep的速度,这是一次非常启发性的体验!
JacobN

7
有些人(不是我)grep -F更喜欢fgrep
Walter Tross 2014年

2
我的理解是,LANG=C(而不是LC_ALL=C)就足够了,并且更容易键入。
Walter Tross 2014年

2
@Adrian fgrep是另一种写作方式grep -F,这man fgrep将告诉您。某些版本的用户man还说,前者不建议使用后者,但是较短的形式太方便了,以致于无法使用。
Walter Tross

36

如果您有多核CPU,我真的建议您使用GNU parallel。要并行使用grep大文件:

< eightygigsfile.sql parallel --pipe grep -i -C 5 'db_pd.Clients'

根据磁盘和CPU的不同,读取较大的块可能会更快:

< eightygigsfile.sql parallel --pipe --block 10M grep -i -C 5 'db_pd.Clients'

您的问题尚不清楚,但其他选择grep包括:

  • 放下-i旗帜。
  • -F标志用于固定字符串
  • 禁用NLS与 LANG=C
  • 用该-m标志设置最大匹配数。

2
如果是实际文件,请使用--pipepart代替--pipe。它快得多。
Ole Tange

这种用法不支持包含空间的模式,我们需要这样使用:parallel --pipe --block 10M“ / usr / bin / grep -F -C5 -e'动物保健和宠物'”
zw963

<并行命令前面的字符是什么意思?
elcortegano

1
@elcortegano:这就是所谓的I / O重定向。基本上,它从以下文件名读取输入。类似于cat file.sql | parallel ...但避免使用UUOC。GNU parallel还提供了一种使用读取文件输入的方法parallel ... :::: file.sql。HTH。
史蒂夫,

10

一些小改进:

  • 如果可以,请删除-i选项,不区分大小写的速度非常慢。

  • 更换.\.

    单点是匹配任何字符的正则表达式符号,这也很慢


3

两条攻击线:

  • 您确定要使用-i,还是可以摆脱它?
  • 您还有更多核心可以玩吗?grep是单线程的,因此您可能希望以不同的偏移量启动更多线程。

1
< eightygigsfile.sql parallel -k -j120% -n10 -m grep -F -i -C 5 'db_pd.Clients'  

如果您需要搜索多个字符串,则grep -f strings.txt可以节省大量时间。以上是我目前正在测试的内容的翻译。-j和-n选项值似乎最适合我的用例。-F grep也有很大的不同。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.