使用 mysqli_query 的 Longtext 最大内存错误

Longtext max memory error using mysqli_query

我工作的公司使用 Kayako 来管理其支持票。我打算制作一个外部网络应用程序,从一家公司获取所有票证并显示历史记录。

我正在使用 mysqli_query 连接到数据库。

$link = mysqli_connect($serverName, $userName, $password, $dbName);
$sql = "SELECT ticketid, fullname, creator, contents FROM swticketposts";
$result = mysqli_query($link, $sql) or die(mysqli::$error);

问题是 mySQL 中的 "contents" table 使用了 LONGTEXT 数据类型。 尝试使用 php 读取此数据会给我超时或最大内存使用错误。

第 49 行是 $result = mysqli_query 等行。

编辑:在原始 post 中发布了错误的错误信息 致命错误:允许的 134217728 字节内存已用完(已尝试分配 8192 字节)

尝试解决我添加的内存问题:

ini_set('memory_limit', '-1');

这给了我这个超时错误:

致命错误:第 49 行的 C:\xampp\htdocs\test\php\TicketCall.php 中超过 30 秒的最大执行时间

事实是,当我们在 kayako 平台上查看门票时,它会读取相同的内容 table 并立即执行,因此必须有一种方法可以更快地读取这些长文本。怎么超出我的范围了。

无法使用的解决方法:

TLDR;有没有一种方法可以使用 php 和 mysql.

从 longtext 数据类型中读取而不会占用内存和出现超时错误?

首先,您可以考虑将查询更改为如下内容:

 SELECT ticketid, fullname, creator, contents FROM swticketposts WHERE customer = 'something'

过滤掉您的报告不关心的客户信息,从而使您的查询 return 数据更少。它可以节省查询的执行时间。

其次,您不妨使用

 SUBSTRING(contents, 1, 1000) AS contents

代替查询中的 contents。这将使您返回 contents 列的一部分(前一千个字符);它可能(或可能不)足以满足您的需求。

第三,mysqli_一般使用缓冲查询。这意味着当您 运行 查询时,整个结果集都会被写入程序的内存中。这可能就是你的记忆力爆棚的原因。读这个。 http://php.net/manual/en/mysqlinfo.concepts.buffering.php

您可以安排逐行处理您的查询:

 $unbufResult = mysqli_query($link, $sql, MYSQLI_USE_RESULT) or trigger_error($link->error);
 if ($unbufResult ) {
   while ($row = $unbufResult ->fetch_assoc()) {
     /* deal with the data from one row */
   }
 }
 $unbufResult->close();

当您完成这些未缓冲的结果集时,您需要小心使用 close(),因为在您这样做之前,它们会使用您的 MySQL 服务器上的资源。这可能会防止你的内存井喷。 (这里使用 fetch_assoc() 没有什么特别之处;您可以使用任何您希望的方法获取每一行。)

第四,php的内存和时间限制通常针对交互式网站操作进行调整。有时报告生成需要很长时间。将 calls to set_time_limit() 放入你的循环中和周围,像这样。

 set_time_limit (300); /* five minutes */
 $unbufResult = mysqli_query($link, $sql, MYSQLI_USE_RESULT) or trigger_error($link->error);
 if ($unbufResult ) {
   while ($row = $unbufResult ->fetch_assoc()) {
     set_time_limit (30);  /* reset time limit on each row */
     /* deal with the data from one row */
   }
 }
 $unbufResult->close();
 set_time_limit (300); /* set time limit back to five minutes when done reading */