介紹
從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是先排除,然後再排序來選;
刪除所有的表,序列,存儲過程
----刪除所有表
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個字段,使用批處理):
- 單詞插入1w條記錄,merge into 用時22.92s,insert用時(測試兩次3s和12s);如果先select確認,再insert的極端情況,需要1394.37s;
- 單詞更新1w條記錄,merge into用時38.899s,update平均29s;如果先select確認,然後再update的極端情況,需要1200.759s;
- 單次select在0.1s以上,在navicat中單詞select在0.08s以上
總的來說還是merge into性能還是比select+update/insert的組合好