2012-12-11 3 views
2

설명서에 설명 된 일반적인 result() 메서드가 모든 레코드를 즉시로드합니다. 내 애플리케이션은 약 30,000 개의 행을로드해야하며 한 번에 하나씩 제 3 자 검색 색인 API에 제출해야합니다. 분명히 모든 것을 한 번에 메모리에로드하는 것은 잘 작동하지 않습니다 (너무 많은 메모리로 인해 오류가 발생 함).CodeIgniter 활성 레코드 : 한 번에 한 행로드

그럼 내 질문은 루프에서 한 번에 한 행을로드하는 기존 MySQLi API 메서드의 효과를 어떻게 얻을 수 있습니까?

+1

을 나는 네가 할 수 있다고 생각하지 않는다. 'LIMIT'과'OFFSET'을 사용하여 여러 개의 쿼리를로드하려고 시도 했습니까? 1000 ~ 한 번로드 할 수 있습니다. – rmobis

+0

검색 api로 합리적으로 전달할 수있는 것부터 10, 100 또는 1000 등으로 돌아가서 작업하십시오. 그룹 제출이 실패한 경우를 대비하여 무언가를 넣고 검색 API에 다시 제출해야합니다. – cartalot

답변

8

다음은 수행 할 수있는 작업입니다.

이것은 한 번에 하나의 행을 가져옵니다. CodeIgniter 소스 코드를 확인하면 result() 메소드를 실행할 때 코드가 실행된다는 것을 알 수 있습니다. 큰 결과 집합에 메모리를 저장하고자하는 사람들을 위해

+0

감사합니다, @elvispt, 내부 인터페이스에 따라 다르지만, 유일한 옵션 인 것 같습니다. – Jonah

+0

감사합니다! 이전에는 메모리에서 보유 할 수있는 것보다 큰 데이터 세트를 처리해야 할 때 일반 mysql 함수를 사용했습니다. 이것은 더 나은 waaaaay입니다. – Mala

+0

나는 이것이 2 년 내에 더 높게 투표되지 않았다는 것에 놀란다. 이것은 기억을 저장하는 환상적인 방법입니다. 내 쿼리 중 일부는이 없이는 가능하지 않습니다. :) – etherous

0

음, 목적으로 한 행을 반환 row() 방법, 또는 동일 않지만 (물론) 배열을 반환 row_array() 방법을 there'se.

그래서 당신은

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

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

이 루프에서 전체 결과 집합에서 각 행을 가져 뭔가를 할 수 있습니다.
메서드 호출을 통해 모든 것을 가져 와서 반복하는 것과 거의 같습니다.

행을 한 번에 원하는 경우 30.000 통화를 만들거나 모든 결과를 선택하고 한 번에 하나씩 가져 오거나 모두 가져오고 배열을 건너 뜁니다. 나는 지금 어떤 출구도 볼 수 없다.

+0

그러나 전체 세트는 주어진 시간에 메모리에있을 수 없습니다. 행을 선택하고 API로 푸시 한 다음 해당 데이터를 삭제하고 반복합니다. – Jonah

0

글쎄, 문제는 result()가 전체 쿼리 응답을 제공한다는 것입니다. row()은 첫 번째 경우를 반입하고 나머지는 덤프합니다. 그러나 쿼리는 여전히 사용하는 함수의 30 000 행을 가져올 수 있습니다. 당신의 원인이 될 것 맞는 것

한 디자인 :이, 하나 개의 행을 API로 보내 페이지를 업데이트하고 다음 행을 사용

$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)); 

} 

. 페이지가 시간 초과되는 것을 방지합니다. 그러나 30 000 개의 레코드와 새로 고침을하는 데 시간이 걸릴 가능성이 높으므로 LIMIT ?, 11보다 높은 숫자로 조정하고 페이지로드 당 result()foreach() 개의 다중 api로 변경하려고 할 수 있습니다.

+0

불행히도 HTTP 리디렉션은 명령 줄을 통해 호출되므로이 경우 작동하지 않습니다. 그것은 슈퍼 실용적인 솔루션처럼 보이지 않는 ... 나는 데이터베이스 어댑터를 직접 사용해야 할 것 같아요? – Jonah

+0

당신은 여분의 mysql 칼럼을 통해 매분마다 그것을 호출 할 수 있고 그래서 그것은'WHERE api = 'FALSE''를 대신 할 것이다. –

2

:

3.0.0이 는 unbuffered_row 기능이 CodeIgniter의 이후,

모든 방법은 위의 전체를로드합니다 결과를 메모리에 저장합니다 (프리 페치). 큰 결과 세트를 처리하려면 unbuffered_row()를 사용하십시오.

 

이 방법은 행으로 메모리에 전체 결과를 프리 페치하지 않고 단일 결과 행을 반환

()는 않는다. 조회에 둘이 s의 행이 있으면, 현재 행을 리턴하고 내부 데이터 포인터를 앞으로 이동시킵니다.

$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

관련 문제