Java编程记录 --- 数据库&SQL(填充中...)

介绍

从Java编程记录 --- 工具箱(填充中...)文章中拆分出来的一个模块。该模块主要记录,平时遇到的一些sql方面的问题,以便后面查阅使用。下面按照问题场景分类。

随机取页

问题场景

现在需要从表中查询定量(假设1000条数据)的数据(定时加载),而一些数据因为某些问题而无法进行处理,但是又不能废弃掉,所以在处理的时候就进行continue跳过。但是当这部分无法处理的数据堆积达到1000条是,负责处理的线程就会进入空转状态,没有处理任何有用数据。

方案

利用随机取页的方式。

private List<Person> selectPersonInfo(int limit){
    Random r = new Random();
    int sum = dao.queryMessageCountByStatus("user_info", 0);
    //page=0~9
    int page = sum%limit==0?r.nextInt(sum/limit):r.nextInt((sum/limit)+1);
    return dao.getPersonInfo(page*limit, limit); //从0开始
}

mysql:

select * from user_info where status=0 order by insert_time desc limit index,limit;

需要注意的是参数含义:例如,`limit 1, 2`,则表示从第二条记录开始往后取2条;

oracle:

select * from (
    select rownum rn, mi.* from (
        select * from (
            select * from user_info where status=0 order by insert_time desc
        ) where rownum <= (index+limit)
    ) mi
) where rn >= (index+1);

 oracle有点特殊,需要这么写(先排序然后找最大值,再取最小值),而且rownum是从1开始的,所以最小值需要+1;

sqlserver:

select top limit * from user_info where primary_key not in (
    select top index primary_key from user_info order by insert_time desc
) and status=0 order by insert_time desc;

sqlserver是先排除,然后再排序来选;

sqlserver分页排序参考链接

删除所有的表,序列,存储过程

----删除所有表
select 'drop table ' || table_name ||';'||chr(13)||chr(10) from user_tables;
----删除所有序列
select 'drop sequence ' || sequence_name||';'||chr(13)||chr(10) from user_sequences;
----删除所有存储过程
select 'drop procedure ' || object_name||';'||chr(13)||chr(10) from user_objects where object_type='PROCEDURE';

执行完成后会生成删除语句,然后复制执行即可(存储过程的目前没用过);

实现插入或更新

实现插入或更新,若有该主键,则更新,若没有就插入;

mysql:

insert ignore into 表名 (字段1,字段2,...) values(?,?,...) on duplicate key update count = count + ?, time = now();

 update后面直接跟需要更新的字段即可;

oracle:

merge into 表名 using dual on (定位记录的条件(例如:主键=?))
	when matched then update set 字段1=值1, ...
	when no matched then insert(字段1, 字段2, ...)
	values(?, ?, ...);

 举例说明:

merge into user_info ui using dual on (ui.id = ?) 
	when matched then update set status=?
	when no matched then insert(id, name, age, status) 
	values(?, ?, ?, ?);

测试的效率说明(14个字段,使用批处理):

  1. 单词插入1w条记录,merge into 用时22.92s,insert用时(测试两次3s和12s);如果先select确认,再insert的极端情况,需要1394.37s;
  2. 单词更新1w条记录,merge into用时38.899s,update平均29s;如果先select确认,然后再update的极端情况,需要1200.759s;
  3. 单次select在0.1s以上,在navicat中单词select在0.08s以上

总的来说还是merge into性能还是比select+update/insert的组合好

三目运算(类似)

场景

比如我想要统计某表数据在该状态下更新的次数(假设而已)。每次更新时判断待更新的数据中的状态是否和表中的状态相同,若相同则累加,否则则重置为1.;

方案

mysql:

update_count = if(status = ?, update_count + ?, 1)

 oracle:

update_count = decode(status, ?, update_count + ?, 1)

 在navicat中执行测试命令:

select decode('1', '2', 'y', 'n') from dual; --- n
select decode('1', '1', 'y', 'n') from dual; --- y

select decode(1, 2, 'y', 'n') from dual; --- n
select decode(1, 1, 'y', 'n') from dual; --- y

select decode(1, '1' 'y', 'n') from dual; --- y 这个很奇怪

 可以看出在同类型的情况是可以使用的。

格式对应:

decode(比较值, 被比较值1, 比较成功返回的值1, 被比较值2, 比较成功返回的值2, 默认值)

if 比较值=被比较值1
	比较成功返回的值1
else if 比较值=被比较值2
	比较成功返回的值2
else
	默认值
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值