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

标签: Technical PostgreSQL | 发表时间:2018-02-27 20:53 | 作者:老王
出处:https://huoding.com

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

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

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

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

SQL With LIMIT

SQL With LIMIT

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

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

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

SQL Without LIMIT

SQL Without LIMIT

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

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

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

相关 [sql 性能] 推荐:

Oracle SQL性能优化

- - 数据库 - ITeye博客
(1)      选择最有效率的表名顺序(只在基于规则的优化器中有效):. ORACLE的解析器按照从右到左的顺序处理FROM子句中的表名,FROM子句中写在最后的表(基础表 driving table)将被最先处理,在FROM子句中包含多个表的情况下,你必须选择记录条数最少的表作为基础表. 如果有3个以上的表连接查询, 那就需要选择交叉表(intersection table)作为基础表, 交叉表是指那个被其他表所引用的表.

SQL性能调优技巧

- - 数据库 - ITeye博客
Data Model设计的Tip. 以三个范式为基础,业务的独立性和原子性拆分要合适,杜绝Key的冗余和不充分依赖. 对于有NULL值的时候,说明可以拆分为子类, 如果有互斥值,比如两个字段,如果A有值,那么B就不能有值. 隐藏的约束,某个Column为A值,那么另外一个Column就必须为B值,或者某个Column只能是1~20的值.

SQL之性能优化

- - CSDN博客数据库推荐文章
在实际应用中,数据库中的数据会有很多,若要从这些数据表中检索数据,就需要对系统进行优化,提高数据库系统的响应速度,下面就是日常一些查询优化的方法. 索引可以提高数据库查询的速度,提高数据库的访问性能,但同时也会影响数据更新操作(例如插入、修改、删除)的速度. 如果WHERE子句中经常用到的某一列或者某几列创建索引.

Sql性能优化梳理

- - IT瘾-geek
本文主要针对的是关系型数据数据库MySql. 键值类数据库可以参考最简大数据Redis. 先简单梳理下Mysql的基本概念,然后分创建时和查询时这两个阶段的优化展开. 第一层:客户端通过连接服务,将要执行的sql指令传输过来. 第二层:服务器解析并优化sql,生成最终的执行计划并执行. 第三层:存储引擎,负责数据的储存和提取.

优化SQL查询:如何写出高性能SQL语句_xuelinger

- - CSDN博客推荐文章
1、首先要搞明白什么叫执行计划. 执行计划是数据库根据SQL语句和相关表的统计信息作出的一个查询方案,这个方案是由查询优化器自动分析产生欀如一条SQL语句如果用来从一个10万条记录的表中查1条记录,那查询优化器会选择“索引查找”方式,如果该表进行了归档,当前只剩下5000条记录了,那查询优化器就会改变方案,采用 “全表扫描”方式.

如何写出高性能SQL语句

- - Oracle - 数据库 - ITeye博客
优化SQL查询:如何写出高性能SQL语句. 1、首先要搞明白什么叫执行计划. 执行计划是数据库根据SQL语句和相关表的统计信息作出的一个查询方案,这个方案是由查询优化器自动分析产生欀如一条SQL语句如果用来从一个10万条记录的表中查1条记录,那查询优化器会选择“索引查找”方式,如果该表进行了归档,当前只剩下5000条记录了,那查询优化器就会改变方案,采用“全表扫描”方式.

SQL性能优化十条经验

- - CSDN博客推荐文章
尽量避免在一个复杂查询里面使用 LIKE '%parm1%'—— 红色标识位置的百分号会导致相关列的索引无法使用,最好不要用.. 其实只需要对该脚本略做改进,查询速度便会提高近百倍. a、修改前台程序——把查询条件的供应商名称一栏由原来的文本输入改为下拉列表,用户模糊输入供应商名称时,直接在前台就帮忙定位到具体的供应商,这样在调用后台程序时,这列就可以直接用等于来关联了.

查看Oracle性能差的SQL

- - Oracle - 数据库 - ITeye博客
1.查看总消耗时间最多的前10条SQL语句. 2.查看CPU消耗时间最多的前10条SQL语句. 3.查看消耗磁盘读取最多的前10条SQL语句. 已有 0 人发表留言,猛击->> 这里<<-参与讨论. —软件人才免语言低担保 赴美带薪读研.

记一次成功的sql注入入侵检测附带sql性能优化

- Bloger - 博客园-首页原创精华区
很多同学和园友都遇到过sql注入的,其中大部分都是代码的不严谨造成的,都是犯过很多错误才学会认真起来. 但是如果是让你接手一个二等残废的网站,并让你在上面改版,而且不能推翻式改版,只能逐步替换旧的程序,那么你会非常痛苦,例如我遇到的问题:.                                                                                                       .