【数据库专题】实战演示造成数据库全表扫描的坑

简介: 【数据库专题】实战演示造成数据库全表扫描的坑

233.webp.jpg正文


一 创建表


1.1 我们先创建一张学生表:


create table test_student(
    id int primary key auto_increment,
    name varchar(100),
    gender varchar(2),
    age int,
    address varchar(200),
    email varchar(100),
    grade varchar(2)
)


1.2 创建索引


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


create
    procedure test_batch_insert()
begin
    declare cnt int default 0;
while cnt < 100 do insert
    into
        test01.test_student (name,
        gender,
        age,
        address,
        email,
        grade)
    values(concat('unkonwn', cnt),
    '女',
    24 + cnt,
    '大唐长安',
    'libai@tang',
    '2');
set
cnt = cnt + 1;
end while;
end;
call test_batch_insert();

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


二 测试编写SQL进行测试


2.1整个SQL语句里没用where子句


223.png

没有where导致的全表扫描


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


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


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


2.2 添加where子句


查询条件列虽然有索引,但是where筛选条件中使用了is null或者is not null。


我们先给name字段加上索引:


alter table test_student add index name_index(name);


然后看看是否索引有效。

224.webp.jpg


索引有效的情况


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


225.png


is null导致的全表扫描


226.png


is not null导致的全表扫描


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


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


查询条件列虽然有索引,但是where筛选条件中使用了!=或者<>操作符。


我们还是基于上面的查询语句做下变更:


227.png


使用!=导致的全表扫描


228.png


使用<>导致的全表扫描


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


229.png


使用in的时候可以走索引


查询条件列虽然有索引,但是不恰当地使用了like。


当需要模糊查询的时候,需要避免使用前模糊,我们先来看下使用前模糊造成的后果:


230.png


使用前模糊导致的全表扫描


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


231.webp.jpg

使用后模糊的时候可以走索引


查询条件列虽然有索引,但是在查询条件列上使用了函数或者计算操作。


我们先给年龄字段也加上索引。


alter table test_student add index age_index(age);


然后普通的索引列查询是走索引的,没有问题。


234.webp.jpg


年龄字段正常走索引


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


235.png


索引列加上计算导致的全表扫描


如果使用函数:


115.png


索引列加上函数导致的全表扫描


建议:


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


查询条件列虽然有索引,但是在查询条件列上发生了隐式转换。

比如我们现在有个记录的name字段值为2,然后我们以字符串形式查询时没有问题:


114.png


索引查询


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


113.png


索引列发生隐式转换导致的全表扫描


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


112.png


索引列显式转换


查询条件列虽然有索引,但是在查询条件列上数据的区分度不明显。


我们先来给年级字段也加上索引。


alter table test_student add index grade_index(grade);


然后使用该索引列发起查询:


111.png


索引列数据区分度不大导致的全表扫描


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

相关文章
|
6月前
|
SQL 关系型数据库 数据库
Python SQLAlchemy模块:从入门到实战的数据库操作指南
免费提供Python+PyCharm编程环境,结合SQLAlchemy ORM框架详解数据库开发。涵盖连接配置、模型定义、CRUD操作、事务控制及Alembic迁移工具,以电商订单系统为例,深入讲解高并发场景下的性能优化与最佳实践,助你高效构建数据驱动应用。
749 7
|
人工智能 关系型数据库 OLAP
聚光灯已就位!阿里云瑶池数据库邀你征战Cursor首届实战征文大赛
阿里云AnalyticDB携手Cursor中文社区,正式发起首届实战征文大赛!我们诚邀开发者融合Cursor的智能编程能力与AnalyticDB PostgreSQL提供的Supabase服务进行项目开发,让优秀项目被专家看见、被机遇拥抱!
|
10月前
|
关系型数据库 MySQL 数据库连接
Django数据库配置避坑指南:从初始化到生产环境的实战优化
本文介绍了Django数据库配置与初始化实战,涵盖MySQL等主流数据库的配置方法及常见问题处理。内容包括数据库连接设置、驱动安装、配置检查、数据表生成、初始数据导入导出,并提供真实项目部署场景的操作步骤与示例代码,适用于开发、测试及生产环境搭建。
457 1
|
11月前
|
负载均衡 算法 关系型数据库
大数据大厂之MySQL数据库课程设计:揭秘MySQL集群架构负载均衡核心算法:从理论到Java代码实战,让你的数据库性能飙升!
本文聚焦 MySQL 集群架构中的负载均衡算法,阐述其重要性。详细介绍轮询、加权轮询、最少连接、加权最少连接、随机、源地址哈希等常用算法,分析各自优缺点及适用场景。并提供 Java 语言代码实现示例,助力直观理解。文章结构清晰,语言通俗易懂,对理解和应用负载均衡算法具有实用价值和参考价值。
大数据大厂之MySQL数据库课程设计:揭秘MySQL集群架构负载均衡核心算法:从理论到Java代码实战,让你的数据库性能飙升!
|
10月前
|
SQL 数据建模 关系型数据库
别光知道存数据库了,数据建模才是王道!(入门指南+实战代码)
别光知道存数据库了,数据建模才是王道!(入门指南+实战代码)
2292 4
|
7月前
|
存储 数据库 开发者
Python SQLite模块:轻量级数据库的实战指南
本文深入讲解Python内置sqlite3模块的实战应用,涵盖数据库连接、CRUD操作、事务管理、性能优化及高级特性,结合完整案例,助你快速掌握SQLite在小型项目中的高效使用,是Python开发者必备的轻量级数据库指南。
599 0
|
存储 运维 监控
百万指标,秒级查询,零宕机——时序数据库 TDengine 在 AIOps 中的硬核实战
本篇文章详细讲述了七云团队在运维平台中如何利用 TDengine 解决海量时序数据存储与查询的实际业务需求。内容涵盖了从数据库选型、方案落地到业务挑战及解决办法的完整过程,特别是分享了升级 TDengine 3.x 时的实战经验,给到有需要的小伙伴参考阅读。
595 1
|
存储 缓存 监控
71.7万/秒到1.4万/秒!数据库查询优化实战
在现代计算机系统中,程序的局部性原理是优化性能的关键。通过利用时间局部性和空间局部性,可以显著提升数据访问效率,减少高开销的操作如内存访问和网络 I/O。本文将探讨如何利用空间局部性原理,在实际案例中减少数据库查询量,并通过详细的监控和优化措施确保系统的稳定性和高效性。
71.7万/秒到1.4万/秒!数据库查询优化实战
|
关系型数据库 数据库 数据安全/隐私保护
云数据库实战:基于阿里云RDS的Python应用开发与优化
在互联网时代,数据驱动的应用已成为企业竞争力的核心。阿里云RDS为开发者提供稳定高效的数据库托管服务,支持多种数据库引擎,具备自动化管理、高可用性和弹性扩展等优势。本文通过Python应用案例,从零开始搭建基于阿里云RDS的数据库应用,详细演示连接、CRUD操作及性能优化与安全管理实践,帮助读者快速上手并提升应用性能。
|
SQL 关系型数据库 数据库
国产数据实战之docker部署MyWebSQL数据库管理工具
【10月更文挑战第23天】国产数据实战之docker部署MyWebSQL数据库管理工具
1034 4
国产数据实战之docker部署MyWebSQL数据库管理工具

热门文章

最新文章