前提:我们在使用脚本处理大量数据的时候,会使用模型获取一条数据表数据!一条条处理数据。
方法一:
使用模型自带查询方法
$info = KnowledgeAttachData::findOne(['es_status' => 0]) ;
方法二:
查询一条数据
$info = KnowledgeAttachData::find()->where(['es_status' => 0])->select(['id','kid',
'vector','doc_type','attach_id','tag_ids','author','logo','posttime','question','answer','create_time','update_time','img_url'])
->orderBy($order)->asArray()->one() ;
方法三:
$info = KnowledgeAttachData::find()->where(['es_status' => 0])
->select(['id','kid','vector','doc_type','attach_id','tag_ids','author','logo','posttime','question','answer','create_time','update_time','img_url'])
->orderBy($order)->limit(1)->asArray()->one() ;
脚本代码:
public function actionSynEsData($type = 1){
ini_set('memory_limit', -1); // 增加内存限制
// 判断进程是否已经在执行
$task = "attach/syn-es-data $type";
$task_list = shell_exec("ps aux | grep '{$task}' | grep -vE 'grep|/bin/sh'");
$task_list = explode("\n", $task_list);
$task_list = array_filter($task_list);
if (count($task_list) > 1) {
echo "任务已在执行中" . PHP_EOL;
return;
}
$es1 = new KnowledgeEs();
while (true){
echo date('Y-m-d H:i:s').' start '.PHP_EOL;
#$info = (new KnowledgeAttachData())->findOneData(['es_status' => 0],['id','kid', 'vector','doc_type','attach_id','tag_ids','author','logo','posttime','question','answer','create_time','update_time','img_url']) ;
// $test = KnowledgeAttachData::find()->asArray()->one();
// var_dump( $test); die();
#$sql = KnowledgeAttachData::find()->where(['es_status' => 0])->select(['id','kid','vector','doc_type','attach_id','tag_ids','author','logo','posttime','question','answer','create_time','update_time','img_url'])->limit(1)->createCommand()->getRawSql();
// var_dump($sql); die();
switch ($type){
case 1:
$order = 'id asc' ;
break ;
default:
$order = 'id desc' ;
}
$info = KnowledgeAttachData::find()->where(['es_status' => 0])->select(['id','kid',
'vector','doc_type','attach_id','tag_ids','author','logo','posttime','question','answer','create_time','update_time','img_url'])->orderBy($order)->limit(1)->asArray()->one() ;
错误:查询数量体(上几十万数据量)很大时,$info 获取失败,脚本会被 killed;采用第一个方法、第二个方法 。都会触发killed
原因:
如果没有 limit(1),数据库会扫描所有符合 where 条件的数据行,然后再返回结果,再由 PHP 的 ->one() 去提取一条数据。因此,limit(1) 会显著减少数据库的扫描工作。
解决办法:综上所说,采用第三个方法,加上 limit(1) 可以将“限制数据量”的工作交给数据库而不是 PHP,提高效率。
评论 (0)