实操演示——那些造成数据库全表扫描的坑

 我来答
世纪网络17
2022-07-14 · TA获得超过5960个赞
知道小有建树答主
回答量:2426
采纳率:100%
帮助的人:144万
展开全部

本文所有示例都使用的是MySQL和DBeaver。

为了直观地认识到哪些写法会容易导致全表扫描,我们这里进行实际操作。

我们先创建一张学生表:

在这张表中,除了主键id有主键索引外,其它字段暂时都没有索引。然后再初始化一些数据:

初始化的数据各位可以自行定义,此处仅供参考。

类型为ALL就代表全表扫描,在后面的键列都是空的,说明此次查询没有可以使用的键。

建议: 任何语句包括delete、update等,都一定要加上where条件,除了防止全表扫描,更要防止大规模地误修改了数据。

如果你就是要修改表中的所有数据怎么办?如果你就是不在乎是否走索引怎么做?可以加上 where created_date <= sysdate() ,如此虽然性能上可能没有实质性提升,但好歹显得更加规范了。

此时在执行计划里面可以看到,类型是ref,此次查询使用的键就是我们刚刚创建的索引 name_index ,证明索引有效。然后我们把查询条件的name改为使用 is null 或者 is not null 试试:

我们看到,查询条件列虽然有索引,但是如果使用了 is null 或者 is not null 就全表扫描了。

建议: 在设计表的时候,就应该考虑到,将那些可能会被用作查询条件的列设置为 not null ,不允许该列出现空值,并指定该列的默认值。

但是如果我们使用 <,>,<=,>=,=,between,in 以及部分like的场景,都是可以走索引的,下面我们仅仅针对in的情况给出示例:

但是如果我们使用后模糊查询,就会走索引:

我们在年龄字段虽然加上了索引,但是如果在查询的时候加上了计算:

如果使用函数:

建议:

可以把 ts.age/2 = 11 改成 ts.age = 22 ,计算操作挪到等号右边。

但是如果我们使用数值进行查询,就发生了隐式转换,系统自动将数值转换为字符串再查询:

但是如果我们自己做了显式转换,就没有问题,索引仍旧可以使用:

因为真实数据中的该列值除了1就是2,所以区分度不大时也无法使用索引。

本文持续更新中,欢迎增加。

已赞过 已踩过<
你对这个回答的评价是?
评论 收起
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式