#建测试表
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进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。
评论
其实,许多时候我们无需用力过猛,找到一份松弛感,保持理智清醒、从容自如就好。
11月前

评论
相关阅读
数据库国产化替代深化:DBA的机遇与挑战
代晓磊
1258次阅读
2025-04-27 16:53:22
2025年4月国产数据库中标情况一览:4个千万元级项目,GaussDB与OceanBase大放异彩!
通讯员
731次阅读
2025-04-30 15:24:06
国产数据库需要扩大场景覆盖面才能在竞争中更有优势
白鳝的洞穴
599次阅读
2025-04-14 09:40:20
【活动】分享你的压箱底干货文档,三篇解锁进阶奖励!
墨天轮编辑部
510次阅读
2025-04-17 17:02:24
一页概览:Oracle GoldenGate
甲骨文云技术
478次阅读
2025-04-30 12:17:56
GoldenDB数据库v7.2焕新发布,助力全行业数据库平滑替代
GoldenDB分布式数据库
471次阅读
2025-04-30 12:17:50
优炫数据库成功入围新疆维吾尔自治区行政事业单位数据库2025年框架协议采购!
优炫软件
362次阅读
2025-04-18 10:01:22
给准备学习国产数据库的朋友几点建议
白鳝的洞穴
304次阅读
2025-05-07 10:06:14
XCOPS广州站:从开源自研之争到AI驱动的下一代数据库架构探索
韩锋频道
285次阅读
2025-04-29 10:35:54
国产数据库图谱又上新|82篇精选内容全览达梦数据库
墨天轮编辑部
275次阅读
2025-04-23 12:04:21