Yii2 模型Model的one() 方法查询的坑

Yii2 模型Model的one() 方法查询的坑

周赒
2024-11-05 / 0 评论 / 3 阅读 / 正在检测是否收录...

前提:我们在使用脚本处理大量数据的时候,会使用模型获取一条数据表数据!一条条处理数据。
方法一:

使用模型自带查询方法

$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

评论 (0)

取消