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的組合好

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章