2012-12-17 41 views
0

我試圖抓取來自oracle數據庫表的數據,並想要一個解決方案,使檢查點的行。Oracle數據庫行檢查點

  • 基本上,爬蟲會抓取最多500行,然後它停止 的應用程序來處理數據。 2分鐘後,爬行器必須從最後一行(檢查點)繼續執行 。

  • 目前,我正在使用rownumber的解決方案,但結果 指示某些行丟失。

這可能是一個基本問題,但對數據庫沒有經驗。我找不到可接受的解決方案。

回答

2

通常情況下,你不會這樣設計系統。通常情況下,您的應用程序只需打開遊標,獲取500行,在應用程序中處理這些行,獲取下一行500行等。只要不關閉遊標,Oracle就會繼續返回系統的結果當您打開光標時更改編號(SCN)。任何在光標打開後添加的行都不會返回,任何在光標打開後刪除的行都會返回。由於讀者不會阻止Oracle中的編寫者,因此這種方法不會阻止任何其他應用程序使用該表(這在其他數據庫中通常是個問題)。

如果您真的想按照您描述的方式設計系統,您需要有一列(或一組列),您可以一致地進行訂購。這必須是單調遞增的主鍵(例如,序列生成的主鍵)。然後,您可以做類似

SELECT * 
    FROM(SELECT a.*, 
       rownum rn 
      FROM(SELECT * 
        FROM table_name 
       ORDER BY some_key) a 
     WHERE rownum <= MAX_ROW) 
WHERE rn >= MIN_ROW 

當然,用這種分頁查詢的,當你朝表的「結束」讓你的進程將越來越慢。由於您只需要對前500行進行排序,因此獲得前500行的效率相當高。當你讀取9,500到10,000行時,你排序的數據量是數據量的20倍,因此查詢速度可能會降低一個數量級。如果你的桌子很大,這通常會導致性能很差。您可以(稍微)通過添加邏輯來改善性能,即翻轉內部查詢中的順序,並在獲取一半頁面後開始提取「較早」的頁面。

此方法也可能會漏掉行。例如,如果插入提交的事務,那麼您獲取行501-550,然後插入'ID` 501的事務提交,您將看到行502而不是行501.

+1

當然+1。鏈接到Oracle讀一致性文檔 - > http://docs.oracle.com/cd/E11882_01/server.112/e25494/ds_txnman010.htm –

+0

感謝您的詳細解決方案。我無法訪問處理連接的更深層次的代碼,並且由於表格非常大,因此一次抓取所有內容將會使整個服務器發生故障。但我會根據你的解決方案找到一些東西。 – MikeNQ

+0

@MikeNQ - 爲什麼它會「吹響整個服務器」以使用單個光標讀取表格的內容?這遠遠少於重複運行分頁查詢的資源密集程度。而且,正如我所解釋的,在Oracle中,讀者不會阻止作者或讀者,因此您的流程不會阻止任何其他流程執行其工作。 –