#建测试表
drop table if exists t;
CREATE TABLE t (
id int NOT NULL AUTO_INCREMENT PRIMARY KEY comment '自增主键',
dept tinyint not null comment '部门id',
age tinyint not null comment '年龄',
name varchar(30) comment '用户名称',
create_time datetime not null comment '注册时间',
last_login_time datetime comment '最后登录时间'
) comment '测试表';
INSERT INTO t VALUES(1,1,25,'user_1','2018-01-01 00:00:00','2018-03-01 12:00:00');
INSERT INTO t VALUES(2,2,45,'user_2','2018-01-01 00:02:40','2018-01-04 02:37:46');
INSERT INTO t VALUES(3,2,26,'user_3','2018-01-01 00:02:09','2018-01-06 07:34:46');
INSERT INTO t VALUES(4,2,22,'user_4','2018-01-01 20:05:56','2018-01-01 20:48:21');
INSERT INTO t VALUES(5,2,23,'user_5','2018-01-01 00:05:55','2018-01-05 18:19:01');
INSERT INTO t VALUES(6,5,46,'user_6','2018-01-01 12:11:58','2018-01-09 23:31:44');
INSERT INTO t VALUES(7,5,31,'user_7','2018-01-01 00:11:15','2018-01-11 03:46:36');
INSERT INTO t VALUES(8,5,25,'user_8','2018-01-01 00:11:56','2018-01-12 01:16:02');
INSERT INTO t VALUES(9,5,49,'user_9','2018-01-01 00:03:09','2018-01-05 21:09:50');
INSERT INTO t VALUES(10,6,24,'user_10','2018-01-01 00:14:20','2018-01-03 03:30:44');
复制
表初始化后是长这样子的:
我们先看下开发同学写的sql:
select * from t
where case when dept=2
and create_time>='2018-01-01 00:00:00'
and create_time<'2018-01-01 03:00:00'
then age<25
when dept=5
and create_time>='2018-01-01 00:00:00'
and create_time<'2018-01-01 03:00:00'
then age>45
else 1
end;
复制
其执行结果为:
select * from t
where (case when dept=2
and create_time>='2018-01-01 00:00:00'
and create_time<'2018-01-01 03:00:00'
and age>=25
then 0
when dept=5
and create_time>='2018-01-01 00:00:00'
and create_time<'2018-01-01 03:00:00'
and age<=45
then 0
else 1
end) = 1;
复制
这样就很好理解了,最重要的是,该语句在Oracle和SQL Server也兼容。
#初始化序列变量
set @i=1;
#========此处拷贝反复执行15次,生成32万+的测试数据==========
insert into t(dept, age, name, create_time, last_login_time)
select left(rand()*10,1) as dept, #随机生成1~10的整数
FLOOR(20+RAND() *(50 - 20 + 1)) as age, #随机生成20~50的整数
concat('user_',@i:=@i+1), #按序列生成不同的name
date_add(create_time,interval +@i*cast(rand()*100 as signed) SECOND), #生成有时间大顺序随机注册时间
date_add(date_add(create_time,interval +@i*cast(rand()*100 as signed) SECOND), interval + cast(rand()*1000000 as signed) SECOND) #生成有时间大顺序的随机的最后登录时间
from t;
#=====================此处结束反复执行=====================
#创建索引以供测试
create index idx_create_time on t(create_time);
复制
select * from t
where (case when dept=2
and create_time>='2018-01-01 00:00:00'
and create_time<'2018-01-01 03:00:00'
and age<25
then 1
when dept=5
and create_time>='2018-01-01 00:00:00'
and create_time<'2018-01-01 03:00:00'
and age>45
then 1
else 0
end) = 1;
复制
执行出来的结果如下:
我们查看执行计划发现也是全表扫描的:
然后我们使用or进行改造:
select * from t
where ( dept=2
and create_time>='2018-01-01 00:00:00'
and create_time<'2018-01-01 03:00:00'
and age<25
)
or
( dept=5
and create_time>='2018-01-01 00:00:00'
and create_time<'2018-01-01 03:00:00'
and age>45
)
复制
执行出来的结果如下:
执行结果和where条件使用case when一样,再看其执行计划:
文章转载自小灯数据,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。
评论
其实,许多时候我们无需用力过猛,找到一份松弛感,保持理智清醒、从容自如就好。
9月前

评论
相关阅读
【专家观点】罗敏:从理论到真实SQL,感受DeepSeek如何做性能优化
墨天轮编辑部
1203次阅读
2025-03-06 16:45:38
【专家有话说第五期】在不同年龄段,DBA应该怎样规划自己的职业发展?
墨天轮编辑部
1175次阅读
2025-03-13 11:40:53
2025年2月国产数据库大事记
墨天轮编辑部
904次阅读
2025-03-05 12:27:34
2025年2月国产数据库中标情况一览:GoldenDB 3500+万!达梦近千万!
通讯员
817次阅读
2025-03-06 11:40:20
2月“墨力原创作者计划”获奖名单公布
墨天轮编辑部
418次阅读
2025-03-13 14:38:19
AI的优化能力,取决于你问问题的能力!
潇湘秦
394次阅读
2025-03-11 11:18:22
优炫数据库成功应用于国家电投集团青海海南州新能源电厂!
优炫软件
332次阅读
2025-03-21 10:34:08
达梦数据与法本信息签署战略合作协议
达梦数据
272次阅读
2025-03-06 09:26:57
国产化+性能王炸!这套国产方案让 3.5T 数据 5 小时“无感搬家”
YMatrix
258次阅读
2025-03-13 09:51:26
IBM收购数据库厂商DataStax:瞄准向量和AI搜索
深度数据云
250次阅读
2025-02-28 12:04:04