MYSQL查询优化的问题 多条件 in查询
SELECT `userid` FROM `esys_sysusersets` WHERE (  `groupid` = '102' AND `userrole` < '3' ) OR (  `groupid` = '103' AND `userrole` < '3' ) ) 

返回的是一个数组 如果直接把语句放到另一个查询里

in的地方用语句

SELECT `id`,`createat`,`createby`,`clientid`,`contactid`,`contactway`,`contactlog` FROM esys_dbcontactlogs esys WHERE (  ( `createby` = '100'  or `createby` in (SELECT `userid` FROM `esys_sysusersets` WHERE (  `groupid` = '102' AND `userrole` < '3' ) OR (  `groupid` = '103' AND `userrole` < '3' ) )  )  ) AND (  `dstatus` = 1 ) ORDER BY  `id` desc  LIMIT 0,10

[ RunTime:0.0112s ]

SELECT COUNT(id) AS tp_count FROM esys_dbcontactlogs esys WHERE (  ( `createby` = '100'  or `createby` in (SELECT `userid` FROM `esys_sysusersets` WHERE (  `groupid` = '102' AND `userrole` < '3' ) OR (  `groupid` = '103' AND `userrole` < '3' ) )  )  ) AND (  `dstatus` = 1 ) LIMIT 1

[ RunTime:24.0147s ]

in的地方先把语句执行了 返回列表 再进行查询

SELECT `id`,`createat`,`createby`,`clientid`,`contactid`,`contactway`,`contactlog` FROM esys_dbcontactlogs esys WHERE (  ( `createby` = '100'  or `createby` in (659,708,720,725,728,744,757,795,803,833,835,837,847,849,851,856,858,883,884,885,886,887,888,927,932,937,945,947,953,958,963,964,965,966,967,968,1006,1013,1014,1016)  )  ) AND (  `dstatus` = 1 ) ORDER BY  `id` desc  LIMIT 0,10

[ RunTime:0.0007s ]

SELECT COUNT(id) AS tp_count FROM esys_dbcontactlogs esys WHERE (  ( `createby` = '100'  or `createby` in (659,708,720,725,728,744,757,795,803,833,835,837,847,849,851,856,858,883,884,885,886,887,888,927,932,937,945,947,953,958,963,964,965,966,967,968,1006,1013,1014,1016)  )  ) AND (  `dstatus` = 1 ) LIMIT 1

[ RunTime:0.5297s ]

两者效率为什么差这么多呢

esys_dbcontactlogs的数据量在60W左右

2个回答

esys_sysusersets表的数据量大概多少?
第二次SELECT COUNT(id)的查询确认不是因为缓存才这么快?
esys_dbcontactlogs表注意是否命中索引(select前面加EXPLAIN),没有索引的话可以加上。尽量避免使用or等会导致索引失效的方式。

QQ755816
柒伍伍捌壹陆 回复今天是星期五: 谢谢 我好好看看
3 个月之前 回复
xsb_20171227
今天是星期五 回复柒伍伍捌壹陆: http://www.lanxinbase.com/?p=2123
3 个月之前 回复
xsb_20171227
今天是星期五 回复柒伍伍捌壹陆: https://www.runoob.com/mysql/mysql-index.html
3 个月之前 回复
QQ755816
柒伍伍捌壹陆 不过感觉这个方法和我直接先把子查询返回 是一个意思 你说的索引的这个 我还是不太明白
3 个月之前 回复
QQ755816
柒伍伍捌壹陆 SELECT SQL_NO_CACHE COUNT(id) AS tp_count FROM esys_dbcontactlogs esys WHERE ( ( createby = '100' OR createby IN ( ( SELECT userid FROM ( SELECT userid FROM esys_sysusersets WHERE ( groupid = '102' AND userrole < '3' ) OR ( groupid = '103' AND userrole < '3' ) ) AS temp ) ) ) ) AND (dstatus = 1) LIMIT 1
3 个月之前 回复
QQ755816
柒伍伍捌壹陆 查询了网上的办法 在in的子查询外部包裹了一层
3 个月之前 回复
xsb_20171227
今天是星期五 回复柒伍伍捌壹陆: 那其实问题就在对esys_dbcontactlogs的查询上面,注意索引问题就是了
3 个月之前 回复
QQ755816
柒伍伍捌壹陆 esys_sysusersets数据量300以内
3 个月之前 回复
QQ755816
柒伍伍捌壹陆 select SQL_NO_CACHE 后时间还是跟原来的差不多
3 个月之前 回复

你的 createBy上应该建了索引了,如果没有需要建一个普通索引,这样速度更快。
然后sql中尽量不要使用or,第二个速度快是因为你条件里面都是常量。
用我的sql试下,看看速度快不快:

SELECT count(*) tp_count FROM 
(
SELECT
id
FROM
    esys_dbcontactlogs esys 
WHERE
`createby` = '100' AND ( `dstatus` = 1 ) 
 UNION 
 SELECT
id
FROM
    esys_dbcontactlogs esys 
WHERE
`createby` IN ( SELECT `userid` FROM `esys_sysusersets` WHERE  `groupid` in( '102','103' ) AND `userrole` < '3' ) AND ( `dstatus` = 1 ) 
) A
HXNLYW
葫芦胡 回复: ALTER table esys_sysusersets ADD INDEX idx_gu(groupid,userrole); ALTER table esys_dbcontactlogs ADD INDEX idx_c(createby);
3 个月之前 回复
HXNLYW
葫芦胡 回复柒伍伍捌壹陆: 没注意是两个表,加两个索引:
3 个月之前 回复
HXNLYW
葫芦胡 回复柒伍伍捌壹陆: SELECT count(*) tp_count FROM ( SELECT id FROM esys_dbcontactlogs esys WHERE createby = '100' AND ( dstatus = 1 ) UNION SELECT esys.id FROM esys_dbcontactlogs esys ,( SELECT userid FROM esys_sysusersets WHERE groupid in( '102','103' ) AND userrole < '3' ) uu WHERE esys.createby = uu.userid AND ( esys.dstatus = 1 ) ) A
3 个月之前 回复
HXNLYW
葫芦胡 回复柒伍伍捌壹陆: 加一个复合索引吧:ALTER table esys_dbcontactlogs ADD INDEX idx_gc(groupid,createby);
3 个月之前 回复
QQ755816
柒伍伍捌壹陆 SELECT id FROM esys_dbcontactlogs esys WHERE createby IN ( SELECT userid FROM esys_sysusersets WHERE groupid in( '102','103' ) AND userrole < '3' ) AND ( dstatus = 1 ) 单独执行这一部分就相当与全部时间了
3 个月之前 回复
QQ755816
柒伍伍捌壹陆 我也想过union 但是测试出来速度也没有提升
3 个月之前 回复
Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
立即提问