【问题标题】:PHP for repetitive large data and array processing用于重复大数据和数组处理的 PHP
【发布时间】:2012-12-07 18:22:20
【问题描述】:

我的问题确实围绕着大量数据的重复使用。

我有大约 50mb 的数据需要在单个 php 页面执行期间重复交叉引用。使用带有表连接的 sql 查询最容易解决此任务。问题是我需要在很短的时间内处理大量数据以及执行此操作所需的查询数量。

我目前正在做的是将每个表的相关部分(通常超过 30% 或 10k 行)转储到一个数组中并循环。表连接总是在一个字段上,所以我建立了一个非常基本的“索引”来识别哪些行是相关的。

系统正常工作。它已经在我的生产环境中使用了一年多,但现在我正试图从中挤出更多的性能。在我正在分析的一个特定页面上,第二高的总时间归因于循环通过这些数组的增量线。它的命中数为 130 万,总执行时间为 30 秒。这代表了大约 8200 次 sql 查询要执行的工作才能达到相同的结果。

我正在寻找的是遇到过这种情况的其他人。我真的不敢相信我是第一个拥有大量需要用 PHP 处理的数据的人。

谢谢!


非常感谢所有在这里提供建议的人。看起来这里并没有像我希望的那样真正的银弹。我想我最终要做的是混合使用 mysql 内存表和某些版本的分页内存缓存。

【问题讨论】:

  • 这里有很多人用 php 处理大数据。我不确定你的问题是什么。
  • @rambo coder 我想我在这里想要了解的是如何在本地存储数据?如果没有 sql(或我正在使用的 hack),你如何加入?必须有一个比自定义编码更受欢迎、经过测试的解决方案可供人们使用。
  • 您可以将数据存储在适合您特定访问模式的更优化的数据结构中。也有可能您的数据不会经常更改,您可以通过编写一个通过套接字连接回答查询的守护程序将其保存在这种优化的数据结构中的内存中。还有并行处理(将任务分成小块,每个块使用不同的机器)。我的猜测是你可以改进你的代码+数据结构来获得巨大的收益。
  • 并行化完全可以解决这个问题。 1000 个对象中的每一个都可以在任何服务器上创建。我现在使用 memcache 来存储数组,但真正节省我的是前期查询和创建时间,这与循环时间相比是很小的。
  • 我可能已经超前了。我认为您需要确定的第一件事是您非常精通数据库索引。另外,也许研究一下数据仓库方法,比如星型模式。

标签: php sql large-data


【解决方案1】:

此解决方案很大程度上取决于您对数据的处理方式,但我发现,当您尝试在列上查找具有特定值的行时,在数组键中工作的唯一值列会大大加快速度。 这是因为 php 使用哈希表来存储快速查找的键。它比遍历数组或使用 array_search 快数百倍。 但是不看代码例子就很难说了。

从评论中添加:

下一步是使用一些内存数据库。您可以使用memory tables in mysqlSQLite。还取决于您控制多少运行环境,因为这些方法需要的内存比共享主机提供商通常允许的要多。由于分组、排序、聚合函数等,它可能还会简化您的代码。

【讨论】:

  • 这几乎就是我的“索引”所做的。迭代用于处理多个匹配项。
  • 好的。我猜下一步是使用一些内存数据库。您可以在 mysql 或 SQLite (sqlite.org/inmemorydb.html) 中使用内存表。还取决于您控制多少运行环境,因为这些方法需要的内存比共享主机提供商通常允许的要多。由于分组、排序、聚合函数等,它可能还会简化您的代码。
  • 我在 AWS EC2 c1.medium 上运行。数据库位于 AWS RDS 上,也运行 c1.medium。我会查看内存表,我不确定我之前是否听说过它是 mysql 的任何选项。
  • 你可能已经找到了这个链接:dev.mysql.com/doc/refman/5.6/en/memory-storage-engine.html
【解决方案2】:

嗯,我正在研究一种类似的情况,在这种情况下我有大量数据要处理,并且可以选择尝试通过 MySQL 查询来做同样多的事情,或者将其卸载到 PHP。

到目前为止,我的经验是这样的:

  1. PHP 比使用 MySQL 查询慢很多。

  2. MySQL 查询速度只有在我将逻辑塞进单个调用时才可接受,因为调用之间的延迟很严重。

我对 PHP 循环处理少量数据的速度感到特别震惊。我一直在想/希望我做错了什么......

【讨论】:

  • 8200 个查询。它是 OOP,所以每个基本上都实例化 1000 个对象并为它们处理需要 8 个查询的数据。我可以全部重写,但这是一个批处理作业,很多时候这些对象一次使用一个。
  • 如果您正在对每个对象执行简单的“SELECT * FROM WHERE id = ”查询,您可以考虑使用 memcache 单独缓存这些行,这样您就可以先访问 memcache数据库。同样,这取决于您的用例,如果对象在批处理作业中每天只使用一次并且您的缓存始终是“冷的”(意味着它没有缓存任何元素),那么它不会有任何区别。同样,如果我能得到一个代码示例,我很乐意提供帮助。
猜你喜欢
  • 2019-11-09
  • 1970-01-01
  • 2017-06-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多