mysql的limit影响sql使用的索引的选择 ?

前些天,测试人员向我反映有一家企业的通讯录同步接口不返回数据,我查日志

输入图片说明

nginx的相应access.log状态码是499,请求超时,从网上查找资料分析有两种可能:

1.客户端主动断开连接

2.服务端响应超时造成客户端连接中断

问了客户端的开发人员,他们说他们设置响应超时时间为5秒,5s未返回则超时

再查服务器日志

发现整个接口耗时快6s多了

输入图片说明

但是这个接口里面调了两个别的服务的接口,具体还真不知道哪个接口耗时,于是我又在每一步接口的调用的前后加上耗时分析,等运维更新到线上,再查日志

输入图片说明

耗时5799ms, 等于说就是这个getPersonByContacts接口太耗时了

我直接找到该服务的项目,打开xml文件

<select id="getPersonByContacts" resultType="PersonDO" parameterType="java.util.Map">
        SELECT
        *
        FROM Person WHERE enterpriseId = #{enterpriseId}
        <if test="timeModified != null and timeModified != ''">
            and timeModified >= #{timeModified}
        </if>
        ORDER BY timeModified ASC
        <if test="batchNum != null and batchNum > 0">
            limit #{batchNum}
        </if>
    </select>

发现sql是正常的sql,看表结构,enterpriseId和timeModified都加了相应的索引,但是为什么还是这么耗呢?

利用sql执行计划查看

输入图片说明

用的索引是timeModified,竟然扫了200w+行,我一查整个表400w+数据,扫描了半张表... 能不慢麽?

我在想为什么用的是timeModified作为索引而不是enterpriseId呢?

输入图片说明

输入图片说明

没加limit时是选择了enterpriseId,扫描的行数也才28000+行,这个肯定就不会慢了...

难道是limit影响了索引的选择?遇事不决还是要问度娘

https://www.zhihu.com/question/26125418/answer/32246645

输入图片说明

输入图片说明

利用题主说的强制索引试试

输入图片说明

后面想了想是不是可以做个嵌套查询达到同样的选择enterpriseId的效果

输入图片说明

果然是可以的!学习了!排查问题也是一个很好的学习过程!

猜你喜欢

转载自my.oschina.net/hensemlee/blog/1803096