php - 我们可以避免在大量记录中雄辩吗
问题描述
我正在使用 laravel eloquent,并且在数据库中有数千条记录的情况下,所以当使用 eloquent 关系时,我的查询执行速度很慢。我应该避免在这些饱和或任何其他方式中使用 eloquent 吗?
这是mysql查询
$leads=Lead::select($col)
->join("gc_od_leads_detail as ld", "gc_od_leads.leads_id", "=", "ld.ld_leads_id")
->join("gc_od_chat as c", "gc_od_leads.leads_chat_id", "=", "c.chat_id")
->join("gc_od_group as g", "c.chat_group_id", "=", "g.group_octachat_id")
->where('c.chat_tags','sales')
->whereIn('c.chat_group_id',$filter['groups']);
if(!empty($filter['keyword'])) {
$leads=$leads->where(function ($q) use ($filter) {
$q->where('ld_name','like', "%".$filter['keyword']."%")
->orWhere('ld_email','like', "%".$filter['keyword']."%")
->orWhere('ld_phoneno','like', "%".$filter['keyword']."%");
});
}
if(!empty($filter['startDate']) && !empty($filter['endDate'])){
$leads=$leads->whereBetween('leads_created_date', [$filter['startDate']." 00:00:00",$filter['endDate']." 23:59:59"]);
}
$leads=$leads->orderBy('leads_created_date','desc');
return $leads;
}
我在边消息和聊天表中有超过 500 000 条录音。我在 eloquent 中更改了查询并对其进行了调试
询问:
Lead::select('leads_id','leads_chat_id')->with(["detail"=>function($q){
$q->select("ld_leads_id");
}])->with(["chat"=>function($q){
$q->select("chat_id")->where(['chat_status'=>1]);
}])->where("leads_status",1)->get();
Debuging Ouput
array:3 [▼
0 => array:3 [▼
"query" => "select `leads_id`, `leads_chat_id` from `gc_od_leads` where `leads_status` = ?"
"bindings" => array:1 [▼
0 => 1
]
"time" => 14.85
]
1 => array:3 [▼
"query" => "select `ld_leads_id` from `gc_od_leads_detail` where `gc_od_leads_detail`.`ld_leads_id` in (2278918, 2278919, 2278920, 2278921, 2278922, 2278923, 2278924, 22789 ▶"
"bindings" => []
"time" => 0.59
]
2 => array:3 [▼
"query" => "select `chat_id` from `gc_od_chat` where `gc_od_chat`.`chat_id` in (3496457, 3496458, 3496459, 3496460, 3496461, 3496462, 3496463, 3496464, 3496465, 3496466, 34 ▶"
"bindings" => array:1 [▶]
"time" => 4.21
]
]
我在输出上方,您可以看到它首先获取所有潜在客户记录,然后转到潜在客户详细信息和聊天表,如果我只想找出聊天状态 = 1 的潜在客户,它仍然会查询所有潜在客户,这就是我的查询速度变慢的原因
我们在哪里使用 join 它不会以这种方式工作我认为这将节省时间和空间都是我的
解决方案
让我们看一下其中的一部分。
if(!empty($filter['keyword'])) {
$leads=$leads->where(function ($q) use ($filter) {
$q->where('ld_name','like', "%".$filter['keyword']."%")
->orWhere('ld_email','like', "%".$filter['keyword']."%")
->orWhere('ld_phoneno','like', "%".$filter['keyword']."%");
});
}
这种关键字匹配方案本质上是缓慢的,而且是灾难性的。它在 Eloquent 和原生 SQL 中都很慢。如果不进行全表扫描,它就无法在 MySQL 中工作。也就是说,它必须检查表的每一行以寻找匹配项,并且不能在 MySQL 中利用任何索引查找方案。为什么?
column LIKE 'constant%'
可以查看索引column
并快速找到以 . 开头的任何值'constant'
。但
column LIKE '%constant%'
必须查看表中的每个值。前导%
使索引查找无用。
在 MySQL 中,调查MySQL 的 FULLTEXT 搜索作为处理关键字查找的一种方式是明智的。(最新版本的 postgreSQL 可以使用不同类型的索引直接处理此类查询,但不能使用 MySQL。)
推荐阅读
- mysql - 删除字符串样式=";" 带有特殊字符的 sql phpmyadmin
- jhipster - Jhipster 将前端与后端分开部署
- php - 如何找出调用我的 php 文件的内容
- python - 如何使用分类数据和数据框进行预处理
- python - 所以我在文本文档中列出了单词列表,并在按下按钮后更新。单词随机显示
- node.js - 我如何在 mongodb 和 mongoose 中实现这一点
- c - 使用 fgets() 计算子字符串在字符串中出现的次数(C)
- sql - 在 mvc 的 list1 中找到 list2
- django - 来自库目录而不是我的项目的本地开发 Django 静态文件
- java - 如何在 SubscriptionAdminSettings 上设置 setTotalTimeout?