【问题标题】:How big can a php array be before memory concerns should be raised?在提出内存问题之前,php 数组可以有多大?
【发布时间】:2012-08-23 15:22:56
【问题描述】:

我们的应用目前的工作方式如下:

class myClass{

    private $names = array();

    function getNames($ids = array()){
         $lookup = array();

         foreach($ids as $id)
             if (!isset($this->names[$id]))
                $lookup[] = $id;

         if(!empty($lookup)){
              $result;//query database for names where id in $lookup
                      // now contains associative array of id => name pairs
              $this->names = array_merge($this->names, $result);
         }

         $result = array();
         foreach($ids as $id)
             $result[$id] = $this->names[$id];

         return $result;
    }
}

这很好用,但它仍然可以(并且经常这样做)导致多个查询(在这种情况下为 400 多个)。

所以,我正在考虑简单地查询数据库并使用数据库中的每个名称填充 $this->names 数组。

但是我担心数据库中有多少条目我应该开始担心这样做时的内存? (数据库列是varchar(100))

【问题讨论】:

  • 你有多少内存?在高峰访问期间,您的服务通常支持多少并发用户?这些是相关的信息。没有他们,任何答案都是无用的。一般来说,这是一个很容易通过负载测试解决的问题。然后,找到瓶颈并优化。在那之前,让它发挥作用(在合理范围内)。
  • 如果问题是在一般的“用于分发的开源软件”(例如博客软件)中提出的,您会如何处理它?
  • 请参阅:php.net/manual/en/function.memory-get-peak-usage.php。查看第一个贡献的注释。
  • 阅读这篇文章How big are PHP arrays (and values) really?。也许它会帮助你。

标签: php mysql caching memory


【解决方案1】:

你有多少内存?在高峰访问期间,您的服务通常支持多少并发用户?这些是相关的信息。没有他们,任何答案都是无用的。一般来说,这是一个很容易通过负载测试解决的问题。然后,找到瓶颈并优化。在那之前,让它发挥作用(在合理范围内)。

但是...

如果你真的想知道你在看什么......

如果我们假设您不存储多字节字符,那么您有 400 个名称 * 100 个字符(假设每个名称都达到了您的字符数限制)...您正在查看大约 40Kb 的内存。看起来太微不足道了,不是吗?

显然,您将从 PHP 中获得其他开销来保存数据结构本身。您能否使用像SplFixedArray 这样的数据结构而不是普通的array 来更有效地存储内容?可能 - 但您将失去高度优化的 array_* 函数,否则您必须操作列表。

用户会使用您计划在内存中缓冲的每一个条目吗?如果您的应用程序必须使用它们,那么它们有多大并不重要,不是吗?将大量不需要的信息“仅仅因为”保留在内存中并不是一个好主意。您绝对不想做的一件事是在每次页面加载时查询数据库以获取 4000 条记录。至少您需要将这些类型的事务放入内存存储中,例如 memcached 或使用 APC。

这个问题 - 就像计算机科学中的大多数问题一样 - 只是一个受约束的最大化问题。除非您知道可用的变量,否则无法正确解决。

【讨论】:

  • 如果表中有 4000 个条目?那我们应该三思而后行吗?
【解决方案2】:

一旦您获得超过一千项左右的键控查找开始变得非常缓慢(当您访问特定键时会有延迟)。你可以用 ksort() 来解决这个问题。 (我看到脚本从 15 分钟的运行时间缩短到 2 分钟以下,只需添加一个 ksort)

否则你真的只受记忆的限制。

更好的方法是在脚本中构建一组缺失数据,然后使用 IN 列表在一个查询中获取所有数据。

你真的不应该浪费内存来存储用户永远看不到的数据。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-12-27
    • 1970-01-01
    • 1970-01-01
    • 2014-10-30
    • 2012-05-29
    • 2011-12-08
    • 2017-02-06
    • 1970-01-01
    相关资源
    最近更新 更多