在优化我的 Apache + PHP 内存使用时,我偶然发现了一个奇怪的问题。基本上,当尝试绑定 MySQLi 查询的结果时,代码会出现错误消息“致命错误:允许的内存大小为 16777216 字节已用尽(尝试分配 50331646 字节)”。
相关表格如下:
CREATE TABLE `note` (
`noteID` int(11) NOT NULL AUTO_INCREMENT,
`contentID` int(11) NOT NULL,
`text` mediumtext NOT NULL,
PRIMARY KEY (`noteID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `content` (
`contentID` int(11) NOT NULL AUTO_INCREMENT,
`text` varchar(2048) NOT NULL,
`datestamp` datetime NOT NULL,
PRIMARY KEY (`contentID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
爆炸的查询是:
select content.contentID,
content.text,
content.datestamp,
note.noteID,
note.contentID, note.text
from basereality.content as content
inner join basereality.note as note
on content.contentID = note.contentID
where content.contentID = 1028 ;
在服务器上的 MySQL 中运行查询运行良好,返回的“note”大小小于 1 KB。
一件奇怪的事情是它试图分配 50331646 的大小是 0x2FFFFFE 十六进制,这是一个可疑的整数。这几乎就像 PHP 试图分配一个足够大的缓冲区来容纳可能的最大的 mediumtext 字段,而不是实际为检索到的数据分配内存。
任何人都知道解决方法 - 除了增加 PHP 中允许的最大内存?
顺便说一句,其他人也有同样的问题,但似乎不知道如何解决。 内存不足(分配50855936)(尝试分配50331646字节)
爆炸的确切线路是:
$statement->bind_result(
$content_contentID,
$content_text,
$content_datestamp,
$note_noteID,
$note_contentID,
$note_text);
将查询更改为选择“'A test string' as note”,而不是获取列,不再显示大量内存使用情况。
顺便说一句,我确定我不是在尝试检索大数据。这显示了 note 表中 mediumtext 字段的实际长度:
select length(text) from basereality.note;
+--------------+
| length(text) |
+--------------+
| 938 |
| 141 |
| 1116 |
| 431 |
| 334 |
+--------------+