俄罗斯VS沙特直播

目前这个属性仅用于CGLIB代理;对于JDK动态代理(缺省代理)无效。通过实现InitializingBean接口的afterPropertiesSet()方法可以在Bean属性值设置好之后做一些操作,实现DisposableBean接口的destroy()方法可以在销毁Bean之前做一些操作。公司业务人员已经分成了事业部,由于技术的平台性和共享性,技术一直是以研发中心存在的单独部门,没有分开。
返回首页

SQL查询中回表对性能的影响

时间:2018-03-05 11:56来源:知行网www.youyuan-chem.com 编辑:麦田守望者

运营反馈某个功能速度很慢,查了一下,定位到如下 SQL:

select id from user
where name like ‘%foobar%’
order by created_at limit 10;

业务需要,LIKE 的时候必须使用模糊查询,我当然知道这会导致全表扫描,不过速度确实太慢了,直观感受,全表扫描不至于这么慢!

 

我使用的数据库是 PostgreSQL,不过它和 MySQL 差不多,也可以 EXPLAIN:

SQL查询中回表对性能的影响
 

 

SQL With LIMIT

如上所示:先按照 created_at 索引排序,再 filter 符合条件的数据,最后 limit 返回结果,看上去很完美,不过为什么慢呢?出于经验主义,我去掉了 limit 再执行:

select id from user
where name like ‘%foobar%’
order by created_at;

果不其然,速度快了好几倍,再看看对应的 EXPLAIN:

SQL查询中回表对性能的影响
 

 

SQL Without LIMIT

如上所示:去掉 limit 后,根本就没用上索引,直接全表扫描,不过反而更快。

为什么呢?要想搞清楚缘由,你需要理解本例中 SQL 查询的处理流程:当使用 limit 时,因为只是返回几条数据,所以优化器觉得采用一个满足 order by 的索引比较划算;当不使用 limit 时,因为要返回所有满足条件的数据,所以优化器觉得不如直接全表扫描。不过就算知道这些还是不足以解释为什么在本例中全表扫描反而快,实际上这是因为当使用索引的时候,除非使用了 covering index,否则一旦索引定位到数据地址后,这里会有一个「回表」的操作,形象一点来说,就是返回原始表中对应行的数据,以便引擎进行再次过滤(比如本例中的 like 运算),一旦回表操作过于频繁,那么性能无疑将急剧下降,全表扫描没有这个问题,因为它就没用索引,所以不存在所谓「回表」操作。

我应该解释清楚了吧,另外,前面提到了 covering index,有兴趣的自己查吧。

顶一下
(1)
100%
踩一下
(0)
0%
------分隔线----------------------------
标签(Tag):SQL查询 回表对性能
------分隔线----------------------------
发表评论
请自觉遵守互联网相关的政策法规,严禁发布色情、暴力、反动的言论。
评价:
表情:
验证码:点击我更换图片
猜你感兴趣