代码之家  ›  专栏  ›  技术社区  ›  Anmol G

加快使用PHP处理大型文本数据和文件的算法

  •  0
  • Anmol G  · 技术社区  · 6 年前

    下面有两个表:

    1. 文档表-此表包含文件的路径,该文件实际包含HTML内容,并且具有层次结构列

    1. 查找和替换-此表包含要查找和替换的单词(替换字符串可以是链接或HTML本身),其余字段是逗号分隔的ID(表1中的文档ID),用于指示要在哪个文档中替换哪个单词

    简而言之,此过程将允许用户根据第二个表查找和替换关键字,并且只在所需的文档中查找和替换关键字。

    算法的工作原理如下:

    1. 获取文档表中所有记录的计数
    2. 插入一组100条记录(以减少服务器超时)
    3. 使用文档ID和层次结构在这里为每个记录循环100个集合,不获取关键字列表,以及要在此特定文档中替换为的内容(注意,where条件在逗号分隔的字符串上运行)
    4. 使用第一个表中的路径从服务器获取文件并提取HTML内容
    5. 按顺序对每个关键字执行循环,并根据内容中的第二个表替换为所需内容
    6. 创建最终文件并保存在服务器上

    这个过程工作得很好,也得到了预期的结果。

    当数据增加时,问题就开始了。到目前为止,第一个表中大约有50000个条目,因此服务器上的文件数相同。

    第二个表包含大约15000条查找记录,并用用用文档ID分隔的长字符串逗号替换关键字。

    对于如此大量的数据,此过程将运行几天,而这不应该发生。

    数据库使用mysql 5.5,后端是php(laravel 5.4)。操作系统是带有nginx Web服务器的CentOS 7。

    有没有一种方法可以使这个过程更顺利、更省时?感谢您的帮助。

    1 回复  |  直到 6 年前
        1
  •  0
  •   O. Jones    6 年前

    php有一个函数 shell_exec($shellCommand);

    您可能希望使用GNU/Linux shell可访问的程序 sed (stream editor) 做这个替换,而不是把每个文件都拖进PHP,然后再写出来。

    例如,

     $result = shell_exec
          ("cd what/ever/directory; sed 's/this/that/g' inputfile > outputfile");
    

    将读取 what/ever/directory/inputfile ,更改所有 this 字符串到 that ,并将结果写入 what/ever/directory/outputfile . 而且,与PHP相比,它的速度非常快。

    编辑 :为什么这种方法节省了很多时间?

    • Shell程序 sed 已经存在了几十年,并且高度优化。 塞德 与PHP相比,它使用的处理能力要少得多——CPU周期要少得多。所以文件的转换速度更快。
    • 编辑文件的任务需要读取、转换和写入文件。按照您描述的方式执行此操作需要在下一个阶段开始之前完成其中的每个阶段。另一方面, 塞德 是流编辑器。它以并行方式读取、转换和写入所有内容。

    要充分利用这种方法,您需要让您的PHP程序编写比 's/this/that/g' . 你要在一个地方做多次替换 塞德 跑。您可以通过连接如下示例中的编辑说明来完成此操作:

     's/this/that/; s/blue/azul/g; s/red/rojo/g'
    

    单个shell命令的长度大约为100k个字符,因此您可能不会达到这些编辑指令长度的限制。

    建议使用 塞德 我确实建议使用不同的算法。