這兩種方法的執行效率相對其他方法是高效的。即便如此,這兩種方法之間也有著本質上的性能區別,我將通過實驗的方式給大家展示一下這兩種方法,并道出其中的本質差別。

1.創建實驗用表并初始化幾條樣本數據
sec@ora10g> create table t (x number, y varchar2(10));
sec@ora10g> insert into t values (1, \\\’sec\\\’);
sec@ora10g> insert into t values (2, \\\’Andy01\\\’);
sec@ora10g> insert into t values (2, \\\’Andy02\\\’);
sec@ora10g> insert into t values (3, \\\’Anna\\\’);
sec@ora10g> insert into t values (4, \\\’Anna\\\’);
sec@ora10g> insert into t values (5, \\\’John\\\’);
sec@ora10g> commit;
sec@secooler> analyze table t compute statistics for table for all indexes for all indexed columns;

Table analyzed.

sec@ora10g> select * from t;

         X Y
———- ——————–
         1 sec
         2 Andy01
         2 Andy02
         3 Anna
         4 Anna
         5 John

6 rows selected.

2.第一種使用rowid輔助查詢和刪除重復記錄的方法
1)查詢重復記錄
sec@ora10g> SELECT *
  2    FROM t t1
  3   WHERE t1.ROWID <> (SELECT MIN (t2.ROWID)
  4                        FROM t t2
  5                       WHERE t1.x = t2.x)
  6  /

         X Y
———- ——————–
         2 Andy02

BTW:如果想要查詢x和y字段同時重復的內容,可以在上面的子查詢中再添加一個“AND t1.y = t2.y”條件即可。

2)刪除重復記錄
可以簡單的將上面的查詢語句改寫成刪除語句便可完成刪除任務。
sec@ora10g> DELETE FROM t t1
  2        WHERE t1.ROWID <> (SELECT MIN (t2.ROWID)
  3                             FROM t t2
  4                            WHERE t1.x = t2.x)
  5  /

1 row deleted.

可以看到,此時x字段重復的內容已經被刪除了。
sec@ora10g> select * from t;

         X Y
———- ——————–
         1 sec
         2 Andy01
         3 Anna
         4 Anna
         5 John

3.第二種使用分析函數輔助查詢和刪除重復記錄的方法
1)使用分析函數可以快速的定位重復記錄的位置,下面結果中rn值大于1的行即表示重復行。
sec@ora10g> SELECT t1.x,
  2         t1.y,
  3         ROW_NUMBER () OVER (PARTITION BY t1.x ORDER BY t1.ROWID) rn
  4    FROM t t1
  5  /

         X Y                            RN
———- ——————– ———-
         1 sec                           1
         2 Andy01                        1
         2 Andy02                        2
         3 Anna                          1
         4 Anna                          1
         5 John                          1

6 rows selected.

2)進一步使用上面的rn結果作為輔助條件便可得到重復記錄內容
sec@ora10g> SELECT t2.x, t2.y
  2    FROM (SELECT t1.x,
  3                 t1.y,
  4                 ROW_NUMBER () OVER (PARTITION BY t1.x ORDER BY t1.ROWID) rn
  5            FROM t t1) t2
  6   WHERE t2.rn > 1
  7  /

         X Y
———- ——————–
         2 Andy02

3)刪除方法
(1)第一種方法是利用rowid構造delete語句來完成刪除,這種方法效率較低。
sec@ora10g> DELETE FROM t WHERE ROWID IN (
  2    SELECT rowid
  3      FROM (SELECT t1.x,
  4                   t1.y,
  5                   ROW_NUMBER () OVER (PARTITION BY t1.x ORDER BY t1.ROWID) rn
  6              FROM t t1) t2
  7     WHERE t2.rn > 1
  8  )
  9  /

1 row deleted.

(2)第二種方法,可以使用構造中間表t1的方法來完成,這是一種非常高效的去重方法,推薦在具有海量數據的數據庫環境中使用。
sec@ora10g> create table t1 as
  2  SELECT t2.x, t2.y
  3    FROM (SELECT t1.x,
  4                 t1.y,
  5                 ROW_NUMBER () OVER (PARTITION BY t1.x ORDER BY t1.ROWID) rn
  6            FROM t t1) t2
  7   WHERE t2.rn = 1
  8  /

Table created.

sec@ora10g> drop table t;

Table dropped.

sec@ora10g> alter table t1 rename to t;

Table altered.

sec@ora10g> select * from t;

         X Y
———- ——————–
         1 sec
         2 Andy01
         3 Anna
         4 Anna
         5 John

4.比較兩種查詢方法的執行計劃,便可得到兩種方法內在的性能差距的出處。
1)第一種使用rowid輔助查詢的執行計劃如下
sec@ora10g> set autot trace exp
sec@ora10g> SELECT *
  2    FROM t t1
  3   WHERE t1.ROWID <> (SELECT MIN (t2.ROWID)
  4                        FROM t t2
  5                       WHERE t1.x = t2.x)
  6  /

Execution Plan
———————————————————-
Plan hash value: 3924487551

—————————————————————————-
| Id  | Operation           | Name | Rows  | Bytes | Cost (%CPU)| Time     |
—————————————————————————-
|   0 | SELECT STATEMENT    |      |     5 |    55 |     6   (0)| 00:00:01 |
|*  1 |  FILTER             |      |       |       |            |          |
|   2 |   TABLE ACCESS FULL | T    |     6 |    66 |     3   (0)| 00:00:01 |
|   3 |   SORT AGGREGATE    |      |     1 |    11 |            |          |
|*  4 |    TABLE ACCESS FULL| T    |     1 |    11 |     3   (0)| 00:00:01 |
—————————————————————————-

Predicate Information (identified by operation id):
—————————————————

   1 – filter(T1.ROWID<> (SELECT MIN(T2.ROWID) FROM T T2 WHERE
              T2.X=:B1))
   4 – filter(T2.X=:B1)

2)第二種使用分析函數輔助查詢的執行計劃如下
sec@ora10g> SELECT t1.x,
  2         t1.y,
  3         ROW_NUMBER () OVER (PARTITION BY t1.x ORDER BY t1.ROWID) rn
  4    FROM t t1
  5  /

Execution Plan
———————————————————-
Plan hash value: 2335850315

—————————————————————————
| Id  | Operation          | Name | Rows  | Bytes | Cost (%CPU)| Time     |
—————————————————————————
|   0 | SELECT STATEMENT   |      |     6 |    66 |     4  (25)| 00:00:01 |
|   1 |  WINDOW SORT       |      |     6 |    66 |     4  (25)| 00:00:01 |
|   2 |   TABLE ACCESS FULL| T    |     6 |    66 |     3   (0)| 00:00:01 |
—————————————————————————

3)通過比較上面兩個執行計劃可以得到如下結論
第一種方法采用2次TABLE ACCESS FULL,第二種方法采用僅一次TABLE ACCESS FULL。
從執行計劃上可以得出使用分析函數的方法更加的高效。

5.小結
在DBA數據庫維護工作中,重復記錄去除問題往往是不可避免的。在具有海量數據的數據庫中去除重復記錄是一件很艱巨的任務,如果方法選擇不正確,很可能難以完成任務。
我這里介紹的兩種方法都是相對比較高效的,細節之處請慢慢體會。

完成任務的手段和方法很多,只有將維護時間和對生產數據庫的沖擊較少到最低的方法才是可以接受的正確方法。

Good luck.

— The End —

更多關于云服務器域名注冊,虛擬主機的問題,請訪問三五互聯官網:m.shinetop.cn

贊(0)
聲明:本網站發布的內容(圖片、視頻和文字)以原創、轉載和分享網絡內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網站立場,如需處理請聯系客服。郵箱:3140448839@qq.com。本站原創內容未經允許不得轉載,或轉載時需注明出處:三五互聯知識庫 » 【探索】兩種查詢和刪除重復記錄的方法及其性能比較

登錄

找回密碼

注冊

主站蜘蛛池模板: 日韩卡一卡2卡3卡4卡| 双腿张开被5个男人调教电影| 国产成人人综合亚洲欧美丁香花| 99re视频在线| 麻豆成人精品国产免费| 国产精品毛片在线完整版| 国产欧美日韩视频一区二区三区 | 国产色无码精品视频免费| 91精品亚洲一区二区三区| 狠狠亚洲色一日本高清色| 中文成人无字幕乱码精品区| 熟妇人妻无码中文字幕老熟妇| 动漫AV纯肉无码AV电影网| 福利一区二区视频在线| 国精产品一品二品国精在线观看| 东京热一精品无码av| 日本丶国产丶欧美色综合| 欧美中文字幕无线码视频| 隆林| 久久综合国产色美利坚| 天堂网在线.www天堂在线资源| 2020国产激情视频在线观看| 色综合久久蜜芽国产精品| 四虎国产精品永久地址99| 激情久久综合精品久久人妻| 精品国产高清中文字幕| 日韩有码中文字幕av| 亚洲中文字幕人成影院| 亚洲人亚洲人成电影网站色| 平凉市| 国产真人无码作爱免费视频app | 大地资源中文第二页日本| 人妻人人做人碰人人添| 国产高清乱码又大又圆| 日本不卡片一区二区三区| 久久国产成人高清精品亚洲| 久久精品国产免费观看频道| 欧洲熟妇熟女久久精品综合| 人与禽交av在线播放| 午夜AAAAA级岛国福利在线| 亚洲午夜av一区二区|