Yii CDbCommand queryAll在尝试检索大数据集时崩溃

时间:2014-12-01 12:52:23

标签: php apache yii

我正在使用Yii 1.1.14而我正在尝试从oracle 11.2数据库中检索大数据集(~80,000条记录/ 10列)。

我的问题是整个脚本在几分钟后崩溃而没有触发任何错误/异常。 我还检查了php和apache日志,但没有任何错误迹象。

脚本是从浏览器执行的,我只得到一个没有数据的空白页面。

以下是代码:

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.

经过一些调试后,我意识到脚本在$ command-> queryAll()行上失败, 但是当我设置一个限制为60,000条记录(~9MB文件)时,脚本不会失败,我会在页面上打印结果,所以我知道代码工作正常。

我怀疑崩溃与内存消耗有关,但通常会触发错误,我尝试将php.ini中的memory_limit提升到256MB,但这并没有解决。 我还尝试将错误报告设置为E_ALL,以尝试获取任何错误/异常。

我在centos 6服务器上使用apache和php 5.3。

我完全没有想法,如果有人能帮助我,我会非常感激。

编辑: 我发现问题,这是一个内存问题,我发现对于一个~10MB的结果集/ 10MB文件,你需要将php.ini的内存限制设置为256MB(这是很多!),我想我会的不使用Yii AR但发出一个普通的PHP命令。

1 个答案:

答案 0 :(得分:2)

我很难想象一种情况,当必须在页面上打印60K记录时。我建议你不要findAll()但是使用CGridViewCListView中的分页结果:

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

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

重写代码非常简单。例如。如果你在做(即使有范围)

TestData::model()->published()->top(5)->findAll()

只是切断了最后一部分,你有CActiveDataProvider contructor

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

<强>更新

尝试按部分查询:

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