MySQL多字段联合索引且多个值查询的2种写法及性能比较

样例表,其中ab为联合索引:

drop table if exists `demo`;
create table `demo`(
    `id` bigint(20) not null auto_increment comment '主键id',
    `a` varchar(32) not null default '' comment 'a字段',
    `b` varchar(32) not null default '' comment 'b字段',
    primary key (`id`),
    unique key(`a`,`b`)
) engine=innodb auto_increment=1 default charset=utf8mb4 comment='demo表';

样例数据:

insert into `demo`(`a`,`b`) values ('1111','2222'),('3333','4444'),('a','b'),('aa','bb'),('aaa','bbb'),('aaaa','bbbb'),('5555','6666'),('7777','8888');

需求:

(`a`='a' and `b`='b') or (`a`='aa' and `b`='bb') or (`a`='aaa' and `b`='bbb')

查询如何查比较好?有2种方案:

1、直接or连接查询

select * from `demo` where (`a`='a' and `b`='b') or (`a`='aa' and `b`='bb') or (`a`='aaa' and `b`='bbb')


可以使用到索引,type类型为range,对比全表扫描会好一点。

2、union all查询

select * from `demo` where (`a`='a' and `b`='b')
union all
select * from `demo` where (`a`='aa' and `b`='bb')
union all
select * from `demo` where (`a`='aaa' and `b`='bbb')


可以使用到索引,但是相当于进行了3次查询,最终将查询结果汇总。每次查询type类型为const,速度最快。缺点就是sql会太长。

综上所述,如果查询数量较少,可以使用2方法,查询数量较多,可以使用1方法。具体可以结合实际情况测试进行取舍。


觉得内容还不错?打赏个钢镚鼓励鼓励!!👍