提问人:ipel 提问时间:10/13/2023 更新时间:10/14/2023 访问量:90
从 MYSQL 读取时减少 PHP 内存使用量
Reducing PHP memory usage while reading from MYSQL
问:
我必须从 mysql 表中读取所有行,然后将所有行存储在 PHP 数组中。
例:
$res = mysqli_query( $con, "SELECT * FROM myTable WHERE 1 ORDER BY type ASC, added DESC" );
while( $row = mysqli_fetch_assoc( $res ) ) {
$array[$row['cat']][$row['type']][] = $row;
}
该表有 14300 行,大小为 10.8MB
但是当我检查内存使用情况时,我得到大约 74MB,为什么?
例:
echo memory_get_usage(); // return 74.6MB
echo memory_get_peak_usage(); // return 74.6MB
有没有办法加快/优化上述数组的创建?
PS:在mysql表中:type,cat和added是索引
答:
当我检查内存使用情况时,我得到大约 74MB,为什么?
PHP与大多数具有可变内存占用的程序一样,将从少量分配开始,当它接近可用容量时,它将要求操作系统提供更多内存。这会产生执行成本开销,PHP 不知道峰值内存使用量是多少,因此它要求一个块。因此,当它愉快地运行时,它的内存总是比它使用的内存多。
在 MyQSL 中,每条记录都具有相同的结构。因此,它只需要存储一次属性名称。但是 PHP 将其表示为一个或多个数组。每个记录元素还必须具有记录结构的表示形式。
PHP 中的每个数据项都存储在称为 ZVAL 的结构中。这捆绑了大量元数据。特别重要的是数据类型和引用计数(因此PHP知道何时可以丢弃该值)
如果 PHP 只是用名称、zvals 和数据填满内存,那么占用空间会小得多。但是,每次它想要检索一个值时,它都需要对数据进行线性搜索。这将花费大量的时间。它使用索引和哈希来加速变量的取消引用。
除了数据之外(实际上在考虑数据之前),PHP 还需要将 PHP 源代码存储在内存中,并将人类可读的东西转换为更接近硬件理解的内容。我上次检查时,平均大小约为原始代码大小的 3 倍。
有没有办法加快速度
除非您的计算机已经处于交换状态,否则内存使用率不会对性能产生太大影响。但是,根据您没有告诉我们的内容,内存占用很可能有显着减少的余地:大概有一些原因需要读取所有这些数据 - 即您想对数据执行某种转换或将其发送到 PHP 内存以外的地方。但我们不知道那是什么,所以不能建议。
如果只能处理一次数据,请在循环中执行处理。也就是说,甚至没有,只需处理然后被覆盖。$array
$row
$row
这可能只节省了 74MB 的一半。肮脏的小秘密是,它已经将所有 14300 行带入 RAM。然后,您的代码会在 中复制所有内容。有一种方法可以一次获取几行数据,但我推断该技术的缺点比 RAM 的成本更糟糕。mysqli_query
$array
同时,我确实同意@syncbean的回答(套用“不是问题”)。我很久以前就知道,获取我自己的数组的全部结果并不是什么大不了的事情。但是,我仍然采用上述“逐行消费”技术,因为我总是在考虑“速度和空间”。(在机器以 1MHz 的速度运行并拥有 1MB 的 RAM 之前,我学会了编程。SELECT's
评论