mysql我们常用的判断是否存在的方式主要是count或者limit, 然后再在Java代码中进行判断count或者null。
可是那种方式更有效呢?以下是我个人的分析,望能够帮助到大家,若有不正确的地方忘留言指出勿喷🙏
- 方式1 count(1)
// sql
select count(1) as num from lcm_people where name like concat("%",name,"%") and age =#{age}
// java 写法:
int num = xxDao.getCounts(people);
if(num > 0){
// 表示存在
} else {
// 表示不存在
}
- 方式2 limt1
// sql
select 1 as num from lcm_people where name like concat("%",name,"%") and age =#{age} limit 1
// java 写法:
Integer num = xxDao.getCounts(people);
if(null != num){
// 表示存在
} else {
// 表示不存在
}
方式2用limit1替代了count,然后我们再看看sql的执行效率看看那个效率更高些
以下是我在Nivicat随便找的一张表中做的测试
从执行计划中我们看的出这俩这的查询方式、表链接的类型、使用到的索引、扫描的行数等信息都是一致的,但是其执行时间却不相同,此处使用的表中只有几千条数据要是数据了更大差别应该会更明显的
特殊的判断是否存在(不能使用limit1)
- 比如有个需求excel导出功能表中的数据很多,一次性导出过多由于性能问题可能会很慢,因此一般会做个判断限制其导出条数,比如限制一万条如何超过一万条就提醒用户不可导出。
- 那么我们此处就要做一个判断是否存在10000条那么上述的俩种方式count(1)与limit1中后者显然不能用了。
我想到了一种方式
// sql
select 1 from lcm_people where name like concat("%",name,"%") and age =#{age} limit 10000,1
// java 写法:
Integer num = xxDao.getCounts(people);
if(null != num){
// 表示存在
} else {
// 表示不存在
}
但是这里就有一个疑问了,limit1比count(1)效率高可以理解因为limit1只要查到一条就返回结果了,然而limit10000,1也比count(1)的效率高吗?为什么?
MYSQL中:
写的顺序:select … from… where… group by… having… order by… limit [offset,] (rows)
执行顺序:from… where…group by… having… select … order by… limit
根据执行顺序我们看出limit在select之后那么,并且在官方文档中介绍limit作用是从结果集中获取指定的行,另外根据下图的执行计划可以看出limit的影响扫描的行数比例就是where条件后边扫描的比例。
综合上述可以得出limit是先根据where条件查询出来总的数据,然后再在这个结果集的基础上输出limit需要的条数,因此limit 1与limit 10000,1的机制是一样的,count与limit都是where的结果集的基础上做的处理,然而limit是根据偏移量直接返回即可,自然比count在这个结果集的基础上再去统计总数速度快点