读取 65k 行时 PHP/MySQL 挂起

读取 65k 行时 PHP/MySQL 挂起

我正在开发一个处理 IP 地址的 PHP 应用程序。我正在处理包含多达 40 亿行的 mysql 表。

我有一个脚本,目前需要从该表中提取 65536 个地址,当我尝试提取这 65K 行时,mysql<->php 接口无法通过 PHP 甚至 phpMyAdmin 给出响应。如果在命令行中使用,mysql 将在大约 0.2 秒内毫无问题地给出 65K 行。

包含 IP 地址的表有 3 个索引( 1 个唯一索引,2 个主索引),这些索引应该有助于提高速度,但我无法让 mysql 将关联数组返回给 PHP 以继续处理数据。

服务器是一台专用的最新 Xeon 机器,具有约 32GB 内存(我不知道确切的规格)。

有任何线索表明这里可能发生什么事吗?

提前致谢。

答案1

mysqli并且PDO都运行在缓冲模式默认情况下。这意味着您的查询实际上受到 PHP 进程内存限制。

http://php.net/manual/en/mysqlinfo.concepts.buffering.php

[在缓冲模式下],查询结果会立即从 MySQL 服务器传输到 PHP,然后保存在 PHP 进程的内存中。这样可以执行其他操作,例如计算行数和移动(查找)当前结果指针。它还允许在处理结果集时在同一连接上发出进一步的查询。缓冲模式的缺点是较大的结果集可能需要相当多的内存。

你应该php.ini通过增加memory_limit设置来增加 PHP 进程的内存限制,或者你可以告诉查询使用无缓冲模式

无缓冲 MySQL 查询执行查询,然后在数据仍在 MySQL 服务器上等待获取时返回资源。这在 PHP 端占用较少的内存,但会增加服务器的负载。

Mysqli示例:

$mysqli  = new mysqli("localhost", "my_user", "my_password", "world");
$uresult = $mysqli->query("SELECT Name FROM City", MYSQLI_USE_RESULT);

PDO示例:

$pdo = new PDO("mysql:host=localhost;dbname=world", 'my_user', 'my_pass');
$pdo->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, false);

相关内容