PHP查询的大量内存使用量

Dan*_*ack 5 php memory apache mysqli

在优化我的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;
Run Code Online (Sandbox Code Playgroud)

而爆炸的查询是:

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 ;
Run Code Online (Sandbox Code Playgroud)

在服务器上的MySQL中运行查询运行正常,返回的'note'大小不到千字节.

一个奇怪的是它试图分配50331646的大小是十六进制的0x2FFFFFE,这是一个可疑的圆数.这几乎就像PHP试图分配一个足够大的缓冲区来保存最大的中间文本字段,而不是实际为所检索的数据分配内存.

任何人都知道一个解决方法 - 除了增加PHP允许的最大内存?

顺便说一句其他人有同样的问题,但似乎不知道如何解决它. 内存不足(分配50855936)(试图分配50331646字节)

爆炸的确切线是:

$statement->bind_result(
  $content_contentID,
  $content_text,
  $content_datestamp,
  $note_noteID,
  $note_contentID,
  $note_text);
Run Code Online (Sandbox Code Playgroud)

更改查询以选择"'测试字符串'作为注释",而不是获取列不再显示大量内存使用情况.

顺便说一下,我确信我不会尝试检索大数据.这显示了注释表中的mediumtext字段的实际长度:

 select length(text) from basereality.note;
+--------------+
| length(text) |
+--------------+
|          938 |
|          141 |
|         1116 |
|          431 |
|          334 |
+--------------+
Run Code Online (Sandbox Code Playgroud)

Dan*_*ack 4

我找到了答案并在另一个问题中评论:

允许的内存大小 67108864 字节已耗尽

基本上,在旧的MySQL连接器库中,不只是分配“text”字段的实际大小来存储结果,而是分配mediumtext类型的最大可能大小。

即,即使结果字段只有 100 KB,也始终分配 16 MB。

解决此问题最简单也可能是最好的方法是改用新的 MySQLND 连接器,该连接器不会显示此行为。