mysql 中 REGEXP 和IN 的效率对比

实例

为了探索这个问题,新建一个表 t_person

CREATE TABLE `NewTable` (
`id`  int(11) NOT NULL AUTO_INCREMENT ,
`p_name`  varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL ,
`ctime`  datetime NULL DEFAULT NULL ,
`utime`  datetime NULL DEFAULT NULL ,
PRIMARY KEY (`id`)
)
ENGINE=InnoDB
DEFAULT CHARACTER SET=utf8mb4 COLLATE=utf8mb4_general_ci
AUTO_INCREMENT=10001
ROW_FORMAT=COMPACT
;

然后插入一万条数据:

drop procedure if exists my_procedure; 

create procedure my_procedure()
begin
  DECLARE n int DEFAULT 1;
  WHILE n < 10001 DO
    insert into t_person (p_name,ctime,utime) value (CONCAT('name_',n),NOW(), NOW()); 
    set n = n + 1;
  END WHILE;
end

CALL my_procedure();

先用REGEXP检索:

SELECT id
FROM t_person
WHERE 'name_9010,name_9011,name_9012,name_9013,name_9014,name_9015,name_9016, name_9017,name_9018,name_9019,
name_9020,name_9021,name_9022,name_9023,name_9024,name_9025,name_9026, name_9027,name_9028,name_9029' REGEXP p_name 

耗时:49ms

用IN检索:

SELECT id
FROM t_person
WHERE p_name in ( 'name_9010','name_9011','name_9012','name_9013','name_9014','name_9015','name_9016', 'name_9017','name_9018','name_9019',
'name_9020','name_9021','name_9022','name_9023','name_9024','name_9025','name_9026', 'name_9027','name_9028','name_9029')

耗时:7ms

总结:

从上面简单的实验可以看出,用IN的效率是要高于REGEXP的。在实际Java项目中,使用mybatis中的foreach可以很方便的用IN检索,例如:

mybatis:
<select id="selectDevices">
 		select id 
 		from t_device
        where serial_number not in
        <foreach collection="deviceSerialNumbers" item="deviceSerialNumber" index="index" open="(" close=")" separator=",">
            #{deviceSerialNumber}
        </foreach>
</select>
dao
List<String> selectDevices(@Param("deviceSerialNumbers") List<String> deviceSerialNumbers);

后记

前面的内容是在家里写的,由于家里没有项目环境,就只是简单的测试了一下。今天来公司后把用到的REGEXP都替换为IN,检索速度提升了10~15倍,确实在效率上有数量级的差距!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值