从数据库查询大量数据时会出现内容不够的提示: PHP Fatal error: Allowed memory size of 268 435 456 bytes exhausted 这个问题在PHP的官方网站上叫缓冲查询和非缓冲查询(Buffered and Unbuffered queries)。PHP的查询缺省模式是缓冲模式。也就是说,查询数据结果会一次全部提取到内存里供PHP程序处理。这样给了PHP程序额外的功能,比如说,计算行数,将指针指向某一行等。更重要的是程序可以对数据集反复进行二次查询和过滤等操作。但这种缓冲查询模式的缺陷就是消耗内存,也就是用空间换速度。 相对的,另外一种PHP 在PHP编程中,当从数据库查询大量数据时,可能会遇到内存耗尽的问题,这通常由于PHP的默认查询模式——缓冲查询(Buffered queries)导致。缓冲查询会一次性将所有查询结果加载到内存中,以便PHP程序可以自由地处理数据,如计算行数、遍历或进行进一步的查询操作。然而,这种方式在处理大数据量时会消耗大量内存,从而可能导致"Allowed memory size exhausted"的错误。 为了解决这个问题,可以采用非缓冲查询(Unbuffered queries),也称为流式查询(Streaming queries)。非缓冲查询让数据库服务器逐条返回结果,而不是一次性返回所有数据,这样可以减少PHP程序的内存消耗,但会增加数据库服务器的压力,因为它需要保持连接直到所有数据都被读取。 以下是三种不同方式实现非缓冲查询: 1. **使用mysqli扩展**: ```php $mysqli = new mysqli("localhost", "my_user", "my_password", "world"); $uresult = $mysqli->query("SELECT Name FROM City", MYSQLI_USE_RESULT); if ($uresult) { while ($row = $uresult->fetch_assoc()) { echo $row['Name'] . PHP_EOL; } } $uresult->close(); ``` 在这里,我们使用`MYSQLI_USE_RESULT`标志启动非缓冲查询。 2. **使用PDO扩展**: ```php $pdo = new PDO("mysql:host=localhost;dbname=world", 'my_user', 'my_pass'); $pdo->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, false); $uresult = $pdo->query("SELECT Name FROM City"); if ($uresult) { while ($row = $uresult->fetch(PDO::FETCH_ASSOC)) { echo $row['Name'] . PHP_EOL; } } ``` 在PDO中,通过设置`PDO::MYSQL_ATTR_USE_BUFFERED_QUERY`为`false`来禁用缓冲查询。 3. **使用旧版mysql扩展**(不推荐,仅作参考): ```php $conn = mysql_connect("localhost", "my_user", "my_pass"); $db = mysql_select_db("world"); $uresult = mysql_unbuffered_query("SELECT Name FROM City"); if ($uresult) { while ($row = mysql_fetch_assoc($uresult)) { echo $row['Name'] . PHP_EOL; } } ``` 在旧版mysql扩展中,使用`mysql_unbuffered_query`函数执行非缓冲查询。 通过采用非缓冲查询,可以有效地处理大量数据,避免内存耗尽的问题。但是,需要注意的是,这种方法会增加数据库服务器的负载,因此在选择查询模式时应根据实际情况权衡内存使用和数据库压力。 此外,优化查询策略也是解决内存问题的重要手段。比如,使用更精确的WHERE子句减少返回的数据量,分批处理大数据,或者利用存储过程和视图来简化查询。还可以考虑调整PHP的内存限制,但这是临时解决方案,可能不适合长期使用。 在实际项目中,结合使用非缓冲查询和适当的查询优化技术,可以有效地管理大量数据的查询,保证程序的稳定运行,同时降低资源消耗。
- 粉丝: 6
- 资源: 899
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助