數據表中根據一列數據進行數據去重:例若有表名爲T_BUFFET_ORDER,包含三個字段:phone,month,status。如今phone字段有重複號碼,根據phone去重:sql
delete from T_BUFFET_ORDER where phone in (select phone from T_BUFFET_ORDER group by PHONE HAVING count(PHONE)>1) and ROWID not in (select min(ROWID) from T_BUFFET_ORDER group by PHONE HAVING count(PHONE)>1);
根據多列數據去重,好比根據phone和month兩個字段做爲去重依據。session
delete from T_BUFFET_ORDER a where (a.phone,a.month) in (select phone,month from T_BUFFET_ORDER group by phone,month having count(*) > 1) and rowid not in (select min(rowid) from T_BUFFET_ORDER group by phone,month having count(*)>1)
索引的重要性:優化
以 前沒有過多的關注過索引,今天遇到一個問題,一個普通的電話號碼抽獎資格表,裏邊一共40萬數據。以前沒有建立任何主鍵,聯合主鍵和索引等等。今天忽然發 現一個每隔一小時的定時任務居然第一次沒有作完,第二個就直接起來了。形成鎖表。日誌後臺druid報了大量的慢語句錯誤。一條update居然是須要 10S,這是什麼樣的牛速。果斷創建了聯合主鍵。操做40萬數據的更新,6秒鐘,輕鬆搞定。(每1000條作一次批量更新操做,防止session超 時)。ui
alter table T_BUFFET_ORDER add constraints buffet_order_pk primary key (phone,month);
count(1)與count(*)比較: 日誌
若是你的數據表沒有主鍵,那麼count(1)比count(*)快 code
若是有主鍵的話,那主鍵(聯合主鍵)做爲count的條件也比count(*)要快 索引
若是你的表只有一個字段的話那count(*)就是最快io
count(*) count(1) 二者比較。主要仍是要count(1)所相對應的數據字段。 若是count(1)是聚索引,id,那確定是count(1)快。可是差的很小的。 由於count(*),自動會優化指定到那一個字段。因此不必去count(?),用count(*),sql會幫你完成優化的table
count詳解:效率
count(*)將返回表格中全部存在的行的總數包括值爲null的行,然而count(列名)將返回表格中除去null之外的全部行的總數(有默認值的列也會被計入).distinct 列名,獲得的結果將是除去值爲null和重複數據後的結果
分頁查詢效率最高的語句
1.無orderby
select * from (select ROWNUM rowno,t.* from t_isag_sms t where t.SEND_DATE BETWEEN TO_DATE('2015/11/01','yyyy/mm/dd') and TO_DATE('2015/11/10','yyyy/mm/dd') and ROWNUM <=20) where rowno >=10;
2.有orderby
select * from (select tt.*,ROWNUM rn from (select t.* from t_isag_sms t where
t.SEND_DATE BETWEEN TO_DATE('2015/11/01','yyyy/mm/dd')
and TO_DATE('2015/11/10','yyyy/mm/dd') order by t.id desc)tt where ROWNUM<=20)where rn>=10;
3.使用HINT使語句得到最佳響應時間
select /*+ FIRST_ROWS */ * from (select ROWNUM rowno,t.* from t_isag_sms t where
t.SEND_DATE BETWEEN TO_DATE('2015/11/01','yyyy/mm/dd')
and TO_DATE('2015/11/10','yyyy/mm/dd') and ROWNUM <=20) where rowno >=10;
select /*+ FIRST_ROWS */ * from (select tt.*,ROWNUM rn from (select t.* from t_isag_sms t where
t.SEND_DATE BETWEEN TO_DATE('2015/11/01','yyyy/mm/dd')
and TO_DATE('2015/11/10','yyyy/mm/dd') order by t.id desc)tt where ROWNUM<=20)where rn>=10;