MySQL的REPLACE、FIND_IN_SET、IN、EXISTS

1. 更新销售品id和下次执行时间

#sourceId迁移前销售品ID
SET @sourceId =‘123456’;
#targetId迁移后销售品ID
SET @targetId =‘258369’;
#@customerId客户ID,支持多个按照’111111,222222’格式
SET @customerId = ‘111111,222222’;
#下一次执行时间 默认在修正ID后10分钟执行
SET @nextExecTime = UNIX_TIMESTAMP(NOW() + INTERVAL 10 MINUTE) * 1000;
#修改周期赠送关系,原id修改为迁移后对应的ID,下次执行时间修改为当前时间推后10分钟
UPDATE test SET good_ids = REPLACE(good_ids, @sourceId, @targetId),next_gift_time = @nextExecTime WHERE good_ids LIKE CONCAT(‘%’, @sourceId, ‘%’) AND FIND_IN_SET(customer_id, @customerId)>0 ;

2. NOW、CURDATE、CURTIME

SELECT NOW(); 查询系统当前时间,返回格式为YYYY-MM-DD HH:MM:SS
2023-06-27 03:32:28
SELECT CURDATE();查询系统当前日期,返回格式为YYYY-MM-DD
2023-06-27
SELECT CURTIME();查询系统当前时间,返回格式为HH:MM:SS
03:32:28

3. INTERVAL 、UNIX_TIMESTAMP

INTERVAL 关键字参考
INTERVAL 关键字表达式
INTERVAL exp UNIT;
这里,exp 表示表达式,例如 1、2、100、200 或其他取决于单位的表达式。单位是计算日期和时间的度量单位,如天、时、分、秒等。
在上面的语法中,INTERVAL 关键字和单位名称都是不区分大小写的。
date + INTERVAL exp UNIT
date - INTERVAL exp UNIT

UNIX_TIMESTAMP(date) 若无参数调用,返回一个无符号整数类型的 UNIX 时间戳('1970-01-01 00:00:00’GMT之后的秒数)。
若用 date 来调用 UNIX_TIMESTAMP(),它会将参数值以’1970-01-01 00:00:00’GMT后的秒数的形式返回。
SET @nextExecTime = UNIX_TIMESTAMP(NOW() + INTERVAL 10 MINUTE) * 1000;
定义@nextExecTime等于当前时间加上十分钟然后获取秒数时间戳再乘以1000得到毫秒时间戳

4. REPLACE、FIND_IN_SET、LIKE

REPLACE(s,s1,s2) 使用字符串 s2 替换字符串 s 中所有的字符串 s1。

FIND_IN_SET(str,strlist):查询字段(strlist)中包含(str)的结果,返回结果为null或记录。可以前面是字段,后面是字符串,也可以前面是字符串,后面是字段。

str 要查询的字符串
strlist 字段名 参数以”,”分隔如( ‘a,b,c,d’);
SELECT FIND_IN_SET(‘b’, ‘a,b,c,d’); 2
SELECT FIND_IN_SET(‘6’, ‘1’); 0

FIND_IN_SET和IN的区别
SELECT * FROM test WHERE FIND_IN_SET(customer_id,‘111111,222222’)
SELECT * FROM test WHERE customer_id IN (‘111111’,‘222222’)
FIND_IN_SET可以当IN来用,当字段在前的时候,后面跟的是字符串常量,相当于就是IN查询
所以如果strlist是常量,则可以直接用IN或者FIND_IN_SET, 否则要用FIND_IN_SET函数。

find_in_set()和like的区别:
主要的区别就是like是广泛的模糊查询,而 find_in_set() 是精确匹配,并且字段值之间用‘,'分开。Find_IN_SET查询的结果要小于like查询的结果。
SELECT * FROM test WHERE FIND_IN_SET(‘AADDPECE8E4B72AE’,good_ids)
SELECT * FROM test WHERE good_ids LIKE ‘%AADDPECE8E4B72AE%’

5. IN和EXISTS的区别

SELECT * FROM a WHERE EXISTS(SELECT 1 FROM t WHERE event_code=‘TEST_GOODS_EVENT’ AND t.act_code=a.code)
SELECT * FROM a WHERE CODE IN(SELECT act_code FROM t WHERE event_code=‘TEST_GOODS_EVENT’)
SELECT a.* FROM t_act a LEFT JOIN t_strategy t ON t.act_code=a.code WHERE t.event_code=‘GET_GOODS_EVENT’
上面三种的查询结果都是一样的

结论:
in()适合子表比主表数据小的情况
exists()适合子表比主表数据大的情况
当主表数据与子表数据一样大时,in与exists效率差不多,可任选一个使用

IN分析:
当前的in子查询是t表驱动a表
mysql先将t表的数据一次性查出来放到内存中
遍历t表的数据,再去查a表(每次遍历都是一次连接交互,这里会耗资源)
假设t有100000条记录,a有10条记录,会交互100000次数据库;再假设t有10条记录,a有100000记录,只会发生10次交互。

EXISTS分析:
当前exists查询是a表驱动t表
与in不同,exists将a的纪录数查询到内存,因此a表的记录数决定了数据库的交互次数
假设A有10000条记录,B有10条记录,数据库交互次数为10000;假设A有10条,B有10000条,数据库交互次数为10。

所以我们写sql时应当遵循“小表驱动大表“的原则

在oracle中使用IN,其括号内列表允许最大的表达式数为1000,超出1000会报错。但在mysql上执行却是可以的。但是mybatis框架限制了in最多1000条。

Not in 和Not Exists 的 效率
如果查询语句使用了Not In,那么内外表全部进行扫描,没有走索引
Not Exist用到子表中的索引进行查询,所以无论两个表中哪个表大,Not exists 都要比Not in 要快。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值