4

文档中描述的正常result()方法似乎可以立即加载所有记录。我的应用程序需要加载大约 30,000 行,一次一个,将它们提交给第三方搜索索引 API。显然,一次将所有内容加载到内存中效果不佳(由于内存过多而导致错误)。

所以我的问题是,我怎样才能达到传统 MySQLi API 方法的效果,在循环中一次加载一行?

4

4 回答 4

9

这是您可以做的事情。

while ($row = $result->_fetch_object()) {
  $data = array(
    'id'         => $row->id
    'some_value' => $row->some_field_name
  );
  // send row data to whatever api
  $this->send_data_to_api($data);
}

这将得到一排。检查 CodeIgniter 源代码,你会看到当你执行 result() 方法时他们会这样做。

于 2012-12-11T19:00:59.553 回答
4

对于那些想要在大型结果集上节省内存的人:

CodeIgniter 3.0.0 开始,就有了一个unbuffered_row功能,

上述所有方法都会将整个结果加载到内存中(预取)。使用 unbuffered_row() 处理大型结果集。

 

此方法返回单个结果行,而不像 row() 那样将整个结果预取到内存中。如果您的查询不止一行,它会返回当前行并将内部数据指针向前移动。

$query = $this->db->query("YOUR QUERY");

while ($row = $query->unbuffered_row())
{
    echo $row->title;
    echo $row->name;
    echo $row->body;
}

您可以选择传递“对象”(默认)或“数组”以指定返回值的类型:

$query->unbuffered_row();               // object
$query->unbuffered_row('object');       // object
$query->unbuffered_row('array');        // associative array

官方文档:https ://www.codeigniter.com/userguide3/database/results.html#id2

于 2015-11-17T09:03:36.737 回答
0

好吧,事情是result()放弃了查询的整个答复。row()只需获取第一个案例并转储其余案例。但是,无论您使用哪个函数,查询仍然可以获取 30 000 行。

适合您的事业的一种设计是:

$offset = (int)@$_GET['offset'];

$query = $this-db->query("SELECT * FROM table LIMIT ?, 1", array($offset));
$row = $query->row();

if ($row) {

    /* Run api with values */

    redirect(current_url().'?offset'.($offset + 1));

}

这将占用一行,将其发送到 api,更新页面并使用下一行。它还可以防止页面超时。但是,30 000 条记录和刷新很可能需要一段时间,因此您可能希望将您LIMIT ?, 1的数字调整为比1goresult()foreach()每个页面加载多个 api 更高的数字。

于 2012-12-11T18:53:46.140 回答
-1

好吧,有row()方法,它只返回一行作为对象,或者row_array()方法,它做同样的事情但返回一个数组(当然)。

所以你可以做类似的事情

$sql = "SELECT * FROM yourtable";
$resultSet = $this->db->query($sql);
$total = $resultSet->num_rows();

for($i=0;$i<$total;$i++) {
  $row = $resultSet->row_array($i);
}

这会从整个结果集中循环获取每一行。这与获取所有信息并循环访问我相信的方法调用
大致相同。$this->db->query($sql)->result()

如果您一次想要一行,您可以进行 30.000 次调用,或者选择所有结果并一次获取一个,或者您获取所有结果并遍历数组。我现在看不到任何出路。

于 2012-12-11T18:40:45.233 回答