目录

我的学习分享

记录精彩的程序人生

X

SQL查找是否“存在“,别再count了,很耗费时间的

https://blog.csdn.net/qq_35661171/article/details/106880454?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.channel_param&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.channel_param

根据某一条件从数据库表中查询 『有』与『没有』,只有两种状态,那为什么在写SQL的时候,还要SELECT count(*) 呢?

无论是刚入道的程序员新星,还是精湛沙场多年的程序员老白,都是一如既往的count

目前多数人的写法

多次REVIEW代码时,发现如下现象:

业务代码中,需要根据一个或多个条件,查询是否存在记录,不关心有多少条记录。普遍的SQL及代码写法如下

##### SQL写法:
SELECT count(*) FROM table WHERE a = 1 AND b = 2
 
##### Java写法:
int nums = xxDao.countXxxxByXxx(params);
if ( nums > 0 ) {
		//当存在时,执行这里的代码
} else {
		//当不存在时,执行这里的代码
}

是不是感觉很OK,没有什么问题

优化方案

推荐写法如下:

##### SQL写法:
SELECT 1 FROM table WHERE a = 1 AND b = 2 LIMIT 1
 
##### Java写法:
Integer exist = xxDao.existXxxxByXxx(params);
if ( exist != NULL ) {
		//当存在时,执行这里的代码
} else {
		//当不存在时,执行这里的代码

SQL不再使用count,而是改用 LIMIT 1,让数据库查询时遇到一条就返回,不要再继续查找还有多少条了

业务代码中直接判断是否非空即可


之前在网上看到有人问 Derby SQL 分页实现的问题,网上有人给出这样的解决方案,SQL 如下:

SELECT * FROM (
SELECT ROW_NUMBER() OVER() AS rownum, myLargeTable.*
FROM myLargeTable
)
AS tmp
WHERE rownum > 200000 AND rownum <= 200005;

其实,这样的分页查询,性能不理想,我试过在 300W 数据量中采用这种分页方式,需要 20~30秒之久;
其实 Derby 10.6 以上版本有更好的分页支持,直接给出 SQL 实现如下:

SELECT * FROM YOUR_TABLE
OFFSET ? ROWS
FETCH NEXT ? ROWS ONLY;

稍微解释一下:
OFFSET ? ROWS - 是指跳过 ? 条记录
FETCH NEXT ? ROWS ONLY - 是指抓取下一个 ? 条记录

这样分页性能可以提升至毫秒级速度,
希望对遇到同样需求的朋友有帮助···

其实 Derby 是很棒的纯 Java 实现的开源数据库,据说现在最大能支持到 700GB 的数据量,而且正在向 TB 级别进发···
————————————————
版权声明:本文为CSDN博主「zhulx_sz」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/zhulx_sz/article/details/51719029