2011-04-01 40 views
-1

我正在寫一個組件,該組件使用股票報價分析xml供稿,並將結果保存在數據庫中。這個問題相當簡單,除了feed不能遞增閱讀。也就是說,沒有辦法指定您只希望X最後一次報價更改或僅更改比X分鐘更新,比如說。我知道真正的問題是飼料是愚蠢的,供應商應該修理他們的東西,但這不是一個選項atm。解析巨大的XML供稿時處理重複的數據

Feed是一個巨大的xml文件,其中包含提供商的最後100000個股票報價。飼料每分鐘輪詢一次,在此期間大約有50到100次更改報價。其餘部分是重複的引號,它們會一遍又一遍讀取。

在每次對feed進行輪詢時,我將所有引號(使用lxml)解析爲對象。然後,對於每個報價對象,我檢查報價是否已經存在於數據庫中。如果是這樣,我就放棄它,如果沒有,我保存它。這個過程非常浪費,因爲只有大約0.1%是新數據,其餘部分是重複的。爲了優化一下,我通過查詢數據庫一次,在最近X小時內更新報價來創建一個查找表。 (last_update,stock_id)鍵中的引號在數據庫中是唯一的,因此該優化將查詢數減少了大約50%。

但仍然有50k db查詢,每個引號必須單獨檢查,如果存在或不存在,這對數據庫非常重要。

所以我在找的是關於如何使我的提要解析器更快的想法。也許有一種方法來區分上一次獲取的XML文件與新的?

+0

哪個數據庫? – ajreal 2011-04-01 08:41:14

回答

1

Feed的頂部或底部是最近的項目嗎?如果他們位於頂部,那麼當您看到數據庫中已存在的第一個項目時,您可以停止解析。

如果最近的項目持續到最後,您可以緩存引用鍵並在內存中查找它們,並在您訪問非緩存的對象時開始訪問數據庫。或者您可以記住您放入數據庫中的最後一個報價,並且在解析所有您查找的項目時只能點擊數據庫中的項目。

1

你的問題分爲兩個方面:1)如何避免解析你不需要解析的東西; 2)如何避免你不需要的數據庫操作。

如果報價本身非常小,您可能不會從嘗試解決(1)中獲得太多收益。否則,您可以創建一個過濾器(例如使用XSLT或SAX)來放棄您不關心的引號,然後對其餘的DOM進行完整的解析。

要解決(2),通常情況下,區分XML文件可能會非常棘手,因爲您的XML文檔中的空白變化,對某些提供程序來說太常見了,可能會導致誤報,並且您通常需要分析實際的XML結構,而不是簡單的文本逐行比較。如果您不認爲這會對您造成任何問題,您可以探索幾個Stack Overflow主題,但我認爲他們還會證明XML差異仍然有點毛毛,特別是在開源領域:

另一種方法可以工作將使用一個已經更新的東西迅速查找本地或分佈式內存緩存。您將獲得避免嘗試過濾或區分內容的好處,並且如果您正在構建長期基礎架構,則可以隨時調整您的緩存基礎架構以用於其他用例。 OTOH創建可擴展的分佈式緩存基礎架構並不是特別便宜的解決方案。