日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Oracle ROWNUM的陷阱

發布時間:2023/12/18 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Oracle ROWNUM的陷阱 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

先拋出一個問題:

?

我有一張表T,現在我想對表中1/4的記錄作UPDATE操作,我的SQL如下:

Update t set col1='123' where mod(rownum,4)=1

我能夠得到想要的結果嗎?

?

答案是:不能。

我們通過一個實驗來說明一下。

?

創建一個具有百萬條記錄的表:

?

使用mod(rownum,4)=1作謂詞,計劃更新全表1/4的記錄

這張表有百萬條記錄,但該SQL操作feedback的結果竟然是"1 row updated",只有1條記錄被更新。開什么玩笑?

?

UPDATE不行,那我換成查詢怎么樣呢?

仍然只有1條被查詢到。那到底是什么原因導致了這個結果呢?為什么不是預期的1/4的記錄呢?

?

這與ROWNUM偽列的實現機制有關。來看看Oracle官方是如何解釋它的:

ROWNUM是指從表或集合中返回某條記錄的順序值,它只對最終返回的記錄進行分配,未返回的記錄不予分配(返回即表示將結果呈現給客戶端)

?

這句話實際上仍然沒有把它說清楚。下面是我自己的理解:類似于rownum<10或mod(rownum,4)=1這樣的謂詞是屬于FILTER(過濾型)謂詞,這種謂詞需要對侯選集合(例如全表掃描后的侯選集合)進行過濾得到最終結果。在進行過濾操作時,每fetch一條記錄,根據當前的返回順序值預分配ROWNUM,當這條記錄通過FILTER過濾并返回給客戶端,該ROWNUM才實際分配給該條記錄,并使當前返回值+1;如果這條記錄未能通過過濾條件,該記錄被丟棄,當前的返回順序值不變化。

?

現在,我們用上面這段描述來說明上述案例僅返回1條記錄的原因。

  • 首先通過T表的全表掃描得到了侯選集合(不一定就是全表掃描,只是本例是通過全表掃描方式得到侯選集合。如下圖)

  • 從侯選集合中fetch一條記錄,預分配ROWNUM=1,此時mod(1,4)=1,符合FILTER條件(mod(rownum,4)=1),該記錄返回,并將ROWNUM=1實際分配給該記錄,當前ROWNUM變為2
  • 從侯選集合中fetch下一條記錄,預分配ROWNUM=2,此時mod(2,4)=2,不符合FILTER條件,該記錄被丟棄,當前ROWNUM不變化
  • 此后將一直重復步驟3,直至侯選集合被完全遍歷。
  • 最終只有1條記錄被返回。
  • ?

    可以通過一個微調進一步驗證上述過程。如果把SQL改為:

    select count(*) from t where mod(rownum,4)=2;

    會有多少條記錄返回呢?

    ?

    答案是:一條也沒有。

    ?

    結論:

    1、凡是涉及使用ROWNUM作為謂詞條件的,一定要當心上述陷阱:凡是有可能使ROWNUM不能持續分配的操作、函數,均有可能導致類似現象。

    轉載于:https://www.cnblogs.com/6yuhang/p/8253007.html

    總結

    以上是生活随笔為你收集整理的Oracle ROWNUM的陷阱的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。