日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網(wǎng)為廣大站長提供免費(fèi)收錄網(wǎng)站服務(wù),提交前請做好本站友鏈:【 網(wǎng)站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(wù)(50元/站),

點(diǎn)擊這里在線咨詢客服
新站提交
  • 網(wǎng)站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會(huì)員:747

Oracle 分頁查詢與數(shù)據(jù)去重深入理解

 

Oracle 分頁查詢

一、效率高的寫法

**

1.無ORDER BY排序的寫法。(效率最高)

(經(jīng)過測試,此方法成本最低,只嵌套一層,速度最快!即使查詢的數(shù)據(jù)量再大,也幾乎不受影響,速度依然!)

SELECT *

FROM (SELECT ROWNUM AS rowno, t.*

FROM emp t

WHERE hire_date BETWEEN TO_DATE ('20060501', 'yyyymmdd')

AND TO_DATE ('20060731', 'yyyymmdd')

AND ROWNUM <= 20) table_alias

WHERE table_alias.rowno >= 10;

2.有ORDER BY排序的寫法。(效率較高)

(經(jīng)過測試,此方法隨著查詢范圍的擴(kuò)大,速度也會(huì)越來越慢哦!)

SELECT *

FROM (SELECT tt.*, ROWNUM AS rowno

FROM ( SELECT t.*

FROM emp t

WHERE hire_date BETWEEN TO_DATE ('20060501', 'yyyymmdd')

AND TO_DATE ('20060731', 'yyyymmdd')

ORDER BY create_time DESC, emp_no) tt

WHERE ROWNUM <= 20) table_alias

WHERE table_alias.rowno >= 10;

**

二、效率垃圾但又似乎很常用的分頁寫法

**

3.無ORDER BY排序的寫法。(建議使用方法1代替)

(此方法隨著查詢數(shù)據(jù)量的擴(kuò)張,速度會(huì)越來越慢哦!)

SELECT *

FROM (SELECT ROWNUM AS rowno, t.*

FROM k_task t

WHERE flight_date BETWEEN TO_DATE ('20060501', 'yyyymmdd')

AND TO_DATE ('20060731', 'yyyymmdd')) table_alias

WHERE table_alias.rowno <= 20 AND table_alias.rowno >= 10;

--TABLE_ALIAS.ROWNO between 10 and 100;

4.有ORDER BY排序的寫法.(建議使用方法2代替)

(此方法隨著查詢范圍的擴(kuò)大,速度會(huì)越來越慢哦!)

SELECT *

FROM (SELECT tt.*, ROWNUM AS rowno

FROM ( SELECT *

FROM k_task t

WHERE flight_date BETWEEN TO_DATE ('20060501', 'yyyymmdd')

AND TO_DATE ('20060531', 'yyyymmdd')

ORDER BY fact_up_time, flight_no) tt) table_alias

WHERE table_alias.rowno BETWEEN 10 AND 20;

5.另類語法。(有ORDER BY寫法)

(語法風(fēng)格與傳統(tǒng)的SQL語法不同,不方便閱讀與理解,為規(guī)范與統(tǒng)一標(biāo)準(zhǔn),不推薦使用。)

WITH partdata AS

(

SELECT ROWNUM AS rowno, tt.*

FROM ( SELECT *

FROM k_task t

WHERE flight_date BETWEEN TO_DATE ('20060501', 'yyyymmdd')

AND TO_DATE ('20060531', 'yyyymmdd')

ORDER BY fact_up_time, flight_no) tt

WHERE ROWNUM <= 20)

SELECT *

FROM partdata

WHERE rowno >= 10;

--6另類語法 。(無ORDER BY寫法)

WITH partdata AS

(

SELECT ROWNUM AS rowno, t.*

FROM k_task t

WHERE flight_date BETWEEN TO_DATE ('20060501', 'yyyymmdd')

AND TO_DATE ('20060531', 'yyyymmdd')

AND ROWNUM <= 20)

SELECT *

FROM partdata

WHERE rowno >= 10;

**

三、分析

**

Oracle的分頁查詢語句基本上可以按照本文給出的格式來進(jìn)行套用。

分頁查詢格式:

SELECT *

FROM (SELECT a.*, ROWNUM rn

FROM (SELECT *

FROM table_name) a

WHERE ROWNUM <= 40)

WHERE rn >= 21

其中最內(nèi)層的查詢SELECT * FROM TABLE_NAME表示不進(jìn)行翻頁的原始查詢語句。ROWNUM <= 40和RN >= 21控制分頁查詢的每頁的范圍。

Oracle 分頁查詢與數(shù)據(jù)去重深入理解

 

上面給出的這個(gè)分頁查詢語句,在大多數(shù)情況擁有較高的效率。分頁的目的就是控制輸出結(jié)果集大小,將結(jié)果盡快的返回。在上面的分頁查詢語句中,這種考慮主要體現(xiàn)在WHERE ROWNUM <= 40這句上。

選擇第21到40條記錄存在兩種方法,一種是上面例子中展示的在查詢的第二層通過ROWNUM <= 40來控制最大值,在查詢的最外層控制最小值。而另一種方式是去掉查詢第二層的WHERE ROWNUM <= 40語句,在查詢的最外層控制分頁的最小值和最大值。這是,查詢語句如下:

SELECT *

FROM (SELECT a.*, ROWNUM rn

FROM (SELECT *

FROM table_name) a)

WHERE rn BETWEEN 21 AND 40

對比這兩種寫法,絕大多數(shù)的情況下,第一個(gè)查詢的效率比第二個(gè)高得多。

這是由于CBO優(yōu)化模式下,Oracle可以將外層的查詢條件推到內(nèi)層查詢中,以提高內(nèi)層查詢的執(zhí)行效率。對于第一個(gè)查詢語句,第二層的查詢條件WHERE ROWNUM <= 40就可以被Oracle推入到內(nèi)層查詢中,這樣Oracle查詢的結(jié)果一旦超過了ROWNUM限制條件,就終止查詢將結(jié)果返回了。

而第二個(gè)查詢語句,由于查詢條件BETWEEN 21 AND 40是存在于查詢的第三層,而Oracle無法將第三層的查詢條件推到最內(nèi)層(即使推到最內(nèi)層也沒有意義,因?yàn)樽顑?nèi)層查詢不知道RN代表什么)。因此,對于第二個(gè)查詢語句,Oracle最內(nèi)層返回給中間層的是所有滿足條件的數(shù)據(jù),而中間層返回給最外層的也是所有數(shù)據(jù)。數(shù)據(jù)的過濾在最外層完成,顯然這個(gè)效率要比第一個(gè)查詢低得多。

Oracle 分頁查詢與數(shù)據(jù)去重深入理解

 

上面分析的查詢不僅僅是針對單表的簡單查詢,對于最內(nèi)層查詢是復(fù)雜的多表聯(lián)合查詢或最內(nèi)層查詢包含排序的情況一樣有效。

這里就不對包含排序的查詢進(jìn)行說明了,下一篇文章會(huì)通過例子來詳細(xì)說明。

下面簡單討論一下多表聯(lián)合的情況。

對于最常見的等值表連接查詢,CBO一般可能會(huì)采用兩種連接方式NESTED LOOP和HASH JOIN(MERGE JOIN效率比HASH JOIN效率低,一般CBO不會(huì)考慮)。在這里,由于使用了分頁,因此指定了一個(gè)返回的最大記錄數(shù),NESTED LOOP在返回記錄數(shù)超過最大值時(shí)可以馬上停止并將結(jié)果返回給中間層,而HASH JOIN必須處理完所有結(jié)果集(MERGE JOIN也是)。那么在大部分的情況下,對于分頁查詢選擇NESTED LOOP作為查詢的連接方法具有較高的效率(分頁查詢的時(shí)候絕大部分的情況是查詢前幾頁的數(shù)據(jù),越靠后面的頁數(shù)訪問幾率越小)。

因此,如果不介意在系統(tǒng)中使用HINT的話,可以將分頁的查詢語句改寫為:

SELECT *

FROM (SELECT a.*, ROWNUM rn

FROM (SELECT *

FROM table_name) a

WHERE ROWNUM <= 40)

WHERE rn >= 21

Oracle 數(shù)據(jù)去重

一、完全重復(fù)數(shù)據(jù)去重方法

具體思路是,首先創(chuàng)建一個(gè)臨時(shí)表,然后將DISTINCT之后的表數(shù)據(jù)插入到這個(gè)臨時(shí)表中;然后清空原表數(shù)據(jù);再講臨時(shí)表中的數(shù)據(jù)插入到原表中;最后刪除臨時(shí)表。

對于表中完全重復(fù)數(shù)據(jù)去重,可以采用以下SQL語句。

--Code

CREATE TABLE "#temp" AS (SELECTDISTINCT * FROM 表名); --創(chuàng)建臨時(shí)表,并把DISTINCT 去重后的數(shù)據(jù)插入到臨時(shí)表中

truncate TABLE 表名; --清空原表數(shù)據(jù)

INSERT INTO 表名 (SELECT * FROM "#temp"); --將臨時(shí)表數(shù)據(jù)插入到原表中

DROP TABLE "#temp"; --刪除臨時(shí)表

二、部分?jǐn)?shù)據(jù)去重方法

我們可以考慮建立臨時(shí)表,將需要判斷重復(fù)的字段、rowid插入臨時(shí)表中,然后刪除的時(shí)候在進(jìn)行比較。

createtable 臨時(shí)表 as

select a.字段1,a.字段2,MAX(a.ROWID) dataid from 正式表 a GROUPBY a.字段1,a.字段2;

deletefrom 表名 a

where a.rowid !=

(

select b.dataid from 臨時(shí)表 b

where a.字段1 = b.字段1 and

a.字段2 = b.字段2

);

commit;

實(shí)例:

-- 根據(jù)MAX(a.rowid)篩選重復(fù)的數(shù)據(jù),獲得一張數(shù)據(jù)不重復(fù)的臨時(shí)表

create table 臨時(shí)表 as

select a.ip,a.port,MAX(a.ROWID) dataid from ipresult

a GROUP BY a.ip,a.port;

-- 刪除正式表中重復(fù)數(shù)據(jù),只保留最新的一條數(shù)據(jù)

delete from ipresult a

where a.rowid !=

(

select b.dataid from 臨時(shí)表 b

where a.ip = b.ip and

a.port= b.port

);

--刪除臨時(shí)表并提交

drop table 臨時(shí)表;

commit;

分享到:
標(biāo)簽:Oracle
用戶無頭像

網(wǎng)友整理

注冊時(shí)間:

網(wǎng)站:5 個(gè)   小程序:0 個(gè)  文章:12 篇

  • 51998

    網(wǎng)站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會(huì)員

趕快注冊賬號,推廣您的網(wǎng)站吧!
最新入駐小程序

數(shù)獨(dú)大挑戰(zhàn)2018-06-03

數(shù)獨(dú)一種數(shù)學(xué)游戲,玩家需要根據(jù)9

答題星2018-06-03

您可以通過答題星輕松地創(chuàng)建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學(xué)四六

運(yùn)動(dòng)步數(shù)有氧達(dá)人2018-06-03

記錄運(yùn)動(dòng)步數(shù),積累氧氣值。還可偷

每日養(yǎng)生app2018-06-03

每日養(yǎng)生,天天健康

體育訓(xùn)練成績評定2018-06-03

通用課目體育訓(xùn)練成績評定