php - 在大数据集上运行whereHas laravel方法会导致mysql崩溃

标签 php mysql laravel crash laravel-5.3

我有一个像这样的Conversation模型:

class Conversation extends Model
{
        use SoftDeletes;

        protected $primaryKey = 'conversation_id';
        protected $dates      = ['deleted_at', 'expert_read_at', 'expert_admin_read_at'];
        protected $fillable   = ['code', 'expert', 'expert_read_at', 'expert_admin', 'expert_admin_read_at'];

        public function questions (){
            return $this->hasMany('App\Question','conversation_id','conversation_id');
        }
}

还有一个像这样的问题模型:

class Question extends Model
    {
        use SoftDeletes;

        protected $primaryKey = 'question_id';
        protected $dates      = ['deleted_at', 'confirmed_expert_admin_at'];
        protected $fillable   = ['text', 'answer', 'conversation_id', 'confirmed', 'is_private', 'email', 'confirmed_expert_admin_at'];

        public function conversation ()
        {
            return $this->belongsTo('App\Conversation', 'conversation_id', 'conversation_id');
        }
    }

如您所见,ConversationQuestion 模型之间存在 hasMany 关系。

在 mysql 数据库中,我有大约 34,000对话记录,每条记录都至少有一个相关的问题

另一方面,前端有一个表单,用户可以输入文本以通过问题text字段进行搜索。

现在我想根据用户输入选择至少有一个问题的对话,然后对结果进行分页。

为此我写道:

function SearchQuestion (Request $request)
            {
                $page            = $request->get('page');
                $questionPerPage = $request->get('question-per-page');
                $text            = $request->get('question-search-text');

                $conversations =
                    Conversation::whereHas('questions', function ($q) use ($text) {
                        if (!empty($text)) {
                            if (!is_numeric($text)) {
                                $q->where('text', 'LIKE', '%' . $text . '%')
                                    ->where('is_private', 0)
                                    ->where('answer', '<>', '')
                                    ->where(function ($q1) {
                                        $q1->where('confirmed', 1)
                                            ->orWhere('confirmed_expert_admin_at', '<=', Carbon::now()->subDay());
                                    });
                            }
                        } else {
                            $q
                                ->where('is_private', 0)
                                ->where('answer', '<>', '')
                                ->where(function ($q1) {
                                    $q1->where('confirmed', 1)
                                        ->orWhere('confirmed_expert_admin_at', '<=', Carbon::now()->subDay());
                                });
                        }
                    }
                    );

                if (!empty($text) and is_numeric($text)) {
                    $conversations->whereCode($text);
                }

                $conversations->orderBy('created_at', 'desc');

                $conversations = $conversations->paginate(5);

                return $conversations;
    }

如您所见,我使用了 whereHas() 方法来搜索每个对话的问题。

但是每次我运行上面的查询时,在第一次尝试中,执行查询需要很长时间12秒,并且在接下来的尝试中不会返回任何结果并且mysql崩溃,我有重新启动 WAMP。

但是,接下来我想使用 with() laravel 方法选择每个选定对话的问题。这样的话,不知道执行查询需要多长时间?

我在 Windows 8 上使用 laravel 5.3 和 wamp 3.0.6 (Apache 2.4.23 – PHP 5.6.25/7.0.10 – MySQL 5.7.14 ) ,64 位。

问题是什么?我能做什么?

更新:
我向两个表的主键和外键添加索引,一切正常。

最佳答案

试试这个。在 whereHas 之前添加 with()

 Conversation::with('questions')->whereHas('questions', function ($q) use ($text) {
              //your conditions on questions rows
    });

关于php - 在大数据集上运行whereHas laravel方法会导致mysql崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41479397/

相关文章:

php - 如何从 mysql_fetch_array 添加值?

php - Laravel - 更新输入文件中上传的文件

sql - MIN/MAX 与 ORDER BY 和 LIMIT

php - MySQL INNER 连接取决于 php 变量是否等于一个字段

java - 将Java连接到MySQL数据库

php - QueryException SQLSTATE[HY000] [2002] 无法连接到 MySQL 服务器

javascript - 如何在不使用 explode 函数的情况下解码 php 中的 json.stringify 数组?

php - 如何在 laravel-validation-rules/credit-card 中获取验证消息

laravel - 如何确定 Laravel 4.2 中模型是否使用软删除

php - 如何为我网站的所有页面设置基本 URL?