2014-12-01 2 views
1

Yii 1.1.14를 사용 중이고 oracle 11.2 데이터베이스에서 큰 데이터 세트 (~ 80,000 레코드/10 개 열)를 검색하려고합니다.큰 데이터 세트를 검색하려고 할 때 CDbCommand queryAll이 충돌 함

내 문제는 오류/예외를 유발하지 않고 전체 스크립트가 단지 몇 분 후에 충돌한다는 것입니다. PHP 및 Apache 로그도 확인했지만 오류가 표시되지 않았습니다.

스크립트는 브라우저에서 실행되며 데이터가없는 빈 페이지 만 반환합니다. 여기

코드입니다 : 나는 스크립트가 $ - 명령> queryAll 메() 라인, 에 실패 실현,

set_time_limit(0); 
$connection = new CDbConnection($dsn,$username,$password); 
$command = $connection->createCommand('SELECT * FROM TEST_DATA'); 
$result = $command->queryAll(); //this is where the script crashes 
print_r($result); 
//Please disregard any typos, I pasted only a portion of the code. 

디버깅 후하지만 (60,000 레코드 ~ 9메가바이트을 제한을 설정하는 경우 파일) 스크립트 도스가 실패하지 않고 결과가 페이지에 인쇄되므로 코드가 제대로 작동한다는 것을 알 수 있습니다.

크래시가 메모리 소비와 관련이 있다고 의심되지만 대개 오류가 발생하고 php.ini의 memory_limit를 256MB로 높이려고했지만 문제가 해결되지 않았습니다. 또한 오류/예외가 발생하도록 시도하기 위해 E_ALL에 오류보고를 설정하려고 시도했습니다.

저는 centos 6 서버에서 PHP 5.3의 아파치를 사용하고 있습니다.

나는 모두 아이디어가 없으며 여기 누군가가 나를 도울 수 있다면 정말 고마워 할 것입니다.

편집 : 문제점을 발견했습니다. 메모리 문제입니다. ~ 10MB 결과 세트/10MB 파일에서 php.ini의 메모리 제한을 256MB로 설정해야합니다. !), 나는 Yii AR을 사용하지 않을 것이지만 일반 PHP 명령을 발행 할 것입니다.

답변

2

60K 레코드를 페이지에 인쇄해야하는 상황을 상상할 수 없습니다. 난 당신이 findAll()을하고 있지만 CGridView 또는 CListView 같이 매겨진 결과를 사용하지 않는 것이 좋습니다 :

$dataProvider=new CActiveDataProvider(TestData::model()); 

$this->widget('zii.widgets.grid.CGridView', array(
    'dataProvider'=>$dataProvider, 
)); 

그것의 아주 간단한 코드를 재 작성 할 수 있습니다. 예 : 당신이

TestData::model()->published()->top(5)->findAll() 
단지 컷 - 오프 마지막 부분

하고있다 (심지어 범위로)하고 있다면 CActiveDataProvider 생성자

new CActiveDataProvider(TestData::model()->published()->top(5)); 

UPDATE 부분에 의해 쿼리

시도에 대한 인수 :

$limit = 1000 ; 
$passes = ceil(Yii::app()->db->createCommand('SELECT COUNT(*) FROM {{test_data}}')->queryScalar()/$limit) ; 

for ($pass = 0 ; $pass < $passes ; $pass++) { 
    $command = Yii::app()->db->createCommand() 
     ->select('*') 
     ->from('{{test_data}}') 
     ->limit($limit) 
     ->offset($pass * $limit) ; 
    $result = $command->queryAll() ; // here is your peace of data 
} 
+0

답장을 보내 주셔서 감사합니다. 위의 예제에서 print_r 명령을 사용하여 간단하게 만들었으나 실제로는 fputcsv ($ handle, $ row)를 사용합니다. 여기서 $ handle = fopen (' php : // output ','w '), 어떤 방법 으로든 충돌합니다 ... 문제는 스크립트가 인쇄 부분에 도착하지 않는다는 것입니다. queryAll qithout에서 오류 메시지가 나타나지 않습니다. 이견있는 사람? – AssafW

+0

DB를 부분별로 쿼리합니다. 업데이트 된 코드를 참조하십시오. –

+0

작동합니다! 나는 이것이 지금까지 가장 좋은 해결책이라고 생각하지만, 이것은 해결책이며 문제를 직접적으로 다루지 않는다. php가 매우 큰 결과 집합 (60k +)을 확실히 처리 할 수 ​​있다고 가정한다.이 대안은 단일 결과에 대해 여러 개의 쿼리를 실행하므로 성능에 영향을 미칩니다. 서버 구성 (php/apache)을 수정하여이 문제를 해결할 수 있을지 궁금합니다. 아무도 나오지 않을 경우 이전에 같은 문제가 발생했는지 기다려 볼 것입니다. 내 문제를 해결하기 때문에 답을 해결책으로 표시 할 것입니다. 다시 한 번 감사드립니다. 정말 감사드립니다. – AssafW

관련 문제