CodeIgniter Active Record:一次加载一行

时间:2012-12-11 18:19:34

标签: php codeigniter mysqli lazy-loading

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

所以我的问题是,如何实现常规MySQLi API方法的效果,在循环中一次加载一行?

4 个答案:

答案 0 :(得分: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()方法时它们将执行此操作。

答案 1 :(得分:3)

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

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;
}
  

您可以选择传递'object'(默认值)或'array'以指定返回值的类型:

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

正式文件:https://www.codeigniter.com/userguide3/database/results.html#id2

答案 2 :(得分:0)

嗯,有 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次调用,要么你选择所有结果并一次一个地获取它们,或者你获取所有结果并遍历数组。我现在看不出任何出路。

答案 3 :(得分: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调整为高于1的数字,然后转到result()foreach()多个api per pageload。