索引已经加了,a 表 people_id 关联 b 表 id, 然后条件是 b 表的某一个字段==1,然后 count(*)
下面是 php 伪代码
$people_ids = Db::name('people_check')->where('admin_id',$value['id'])->column('people_id');
$people1 = Db::name("people")->where('id','in',$people_ids)->where('id_dailu',1)->count();  # 全部检测人数
                
admin_id 加了索引,id_dailu 加了索引。 没有全表扫描
原先写法是 join left,这个是改过的, 这个更慢。 求大佬分析一波
|  |      1jenlors      2021-06-11 10:46:23 +08:00 如果对准确的要求不高可以取模糊值,或者加缓存 | 
|  |      2F281M6Dh8DXpD1g2      2021-06-11 10:47:27 +08:00 不贴执行计划咋分析 | 
|      3liuxingdeyu      2021-06-11 11:20:18 +08:00 你好歹给个 sql 语句和表信息啊,或者给个查询计划。还有就是,为啥 5m 的数据要一下全搞出来,而且还要 join 。话说如果有这样的需求,postgresql 是不性能会好点 | 
|  |      4codespots      2021-06-11 13:15:40 +08:00  1 这是哪个框架的 ORM 写法啊,好歹给个 SQL 语句啊,你这样提问很大程度上限制了回复你问题的人群范围 | 
|  |      5yadgen      2021-06-11 13:25:44 +08:00 in 是全表扫描 | 
|  |      6keepeye      2021-06-11 13:28:04 +08:00 第一步 people_ids 结果集多大?太大的话可能就不走索引了 | 
|      7ebingtel      2021-06-11 14:02:46 +08:00 这个要看 raw sql……调用 count(), 看看对应的 sql 是: "SELECT COUNT(*) FROM (子查询)".还是 SELECT COUNT(*) FROM 表 1  JOIN ... | 
|  |      8Aruforce      2021-06-11 14:08:51 +08:00 不要 in... 会扫描所有的行 | 
|      9ZhaoHuiLiu      2021-06-11 14:16:57 +08:00 via Android 没做这种项目,能否给 mysql 弄两个从数据库。 select people_id from people_check where admin_id=? 上面得到了 people_ids 数组 select count(*) from people where id=? and id_dailu=1 遍历 people_ids 数组生成多个上面的 sql 语句,分别发送给两个从数据库查询,等两个从数据库返回结果,然后结果相加就可以了。 数据库访问慢,优化 sql 语句成效不大,做好主从数据库,解决少于 1 亿条数据的表还是可行的,希望我说的能给你帮助。 | 
|      11wangxin13g      2021-06-11 14:42:14 +08:00  2 @jk1030 某个版本之前的 in 查询是走全表的 然后一堆人看了以前的文章 总是信誓旦旦的说 In 走全表 | 
|  |      12QiangZai      2021-06-11 16:05:01 +08:00 可以想办法用 join 么 | 
|      15jk1030      2021-06-11 16:46:22 +08:00 @Aruforce   我的映像中  in 是区间把  虽然参数多可能会有影响  但是除非达到某些条件不然的话不会是全表的 你是什么版本的 mysql | 
|      16securityCoding      2021-06-11 16:50:41 +08:00 我感觉我是个废人了,连表 sql 根本不会写了... | 
|      17ZhaoHuiLiu      2021-06-11 16:56:24 +08:00 via Android 你们别讨论了,再讨论我也觉得好笑了,500 万数据,假如他 ids 是 10 个值,那么就是 5000 万次比较,然而他还有 id_dailu=1 这个比较就是 5500 万次比较,这只是理论最低值计算。又是单线程处理,又要读取硬盘数据,网络传输数据各种开销你觉得查询会少于 1 秒吗。多搞几台从 mysql 数据库服务器,然后多创建几个 mysql 连接发送到这两台服务器上查询结果,把两台数据库结果归总就可以了 | 
|      18alansfinal      2021-06-11 17:46:10 +08:00 1. 有没有先开启 mysql query log 确认一下实际执行的 raw query 是什么?可以把实际执行的 SELECT 语句贴上来 2. 有没有调用 EXPLAIN 和 SHOW PROFILE 看看实际的 query plan 是什么?不能想当然认为是走索引还是全表扫描 3. $people_ids 是否需要去重?一般有多少个值?如果有很多个的话(极端例子是所有 id 都需要返回)那么肯定是需要全表扫描,慢也正常。解决方法参考 1 楼 | 
|      19y7E6IG8spV7TU8n7      2021-06-11 17:58:22 +08:00 via iPhone 第一个表 admin_id 加索引 第二个 people 表加联合索引 id,id_dailu 试试? | 
|  |      20ch2      2021-06-11 17:58:36 +08:00 in 操作避雷 | 
|  |      22raaaaaar      2021-06-11 18:08:30 +08:00 via Android SQL,explain 发出来看看 | 
|  |      24zhuzhibin      2021-06-11 19:27:02 +08:00 join 数据大 一定会慢吧 | 
|  |      25JJstyle      2021-06-11 20:18:39 +08:00 via iPhone 总的原因在于 in 的 id 太多了,加了索引也没用,提供一个思路:将 ids 排序后按照数量 chunk,比如 50 万一个 chunk,然后每个 chunk 一个异步查询,最终结果求和。 | 
|  |      26xuanbg      2021-06-11 21:45:32 +08:00 @wangxin13g 还有 null 不能索引也一样。。。都是以讹传讹,用旧地图轰炸新目标。 |