2012-10-08 24 views
1

我有一個ML數據庫,其中包含幾萬個文檔,還有一個查詢爲這些文檔的全部或部分文件返回一些簡單的計算值。文檔數量已經增長到「所有文檔」選項不再可靠地運行而沒有超時,並且隨着文檔數量的增長,情況只會變得更糟。顯而易見的解決方案是客戶端應用程序使用其他表單並對結果進行分頁。這是一個脫機批處理流程,所以整體速度不是問題 - 我們只是希望保持個別請求的正常。在XQuery中,如何避免分頁簡單查詢中的性能下降?

查詢的分頁版本是非常簡單的:

declare namespace ns = "http://some.namespace/here" 

declare variable $fromCount external; 
declare variable $toCount external; 

<response> { 
    for $doc in fn:doc()/ns:entity[$fromCount to $toCount] 
    return 
    <doc> omitted for brevity </doc> 
} </response> 

的問題是,查詢速度慢的進一步通過文件設定的請求的頁面;大概是因爲它不得不按順序加載每個文檔,檢查它是否是正確的類型,並在它開始構建響應之前迭代,直到找到$fromCountns:entitys。

一個問題是數據庫中還有其他類型的文檔,所以只使用fn:doc並不是一個現實的選擇(儘管它們在不同的目錄中,因此xdmp:directory()可能是一個選項;我會看看。)

目前還沒有在ns:entity元素上的索引;會有幫助嗎?它總是一個文檔的根節點,並且文檔非常大,所以我很關心索引的大小。另外,該查詢的(緩慢的部分)對元素的不感興趣,只是它存在。

我曾考慮過使用search: api作爲它的內置分頁,但對於一個旨在匹配所有文檔的查詢來說似乎有點矯枉過正;當然可以手動構建search:search()將在內部構建的查詢。

看來我真正需要的是數據庫中某種類型的所有根節點的有效列表。 Marklogic是否保留這樣的事情?如果不是索引可以解決問題嗎?


編輯:原來,在我的情況,答案是使用xdmp:directory()選項,因爲ML顯然存儲所有文件的速度快,在內存中的列表。儘管如此,如果這個問題的更一般的解決方案,它肯定會引起人們的興趣,所以我會在這裏留下問題。

+0

如果你能詳細說明你的查詢應該做什麼,這將有所幫助。是的,ns:entity上的元素範圍索引可能有助於加速分頁查詢。另外,如果你只關心元素的存在,而不是它的值,並且每個xs:entity都是一個片段,那麼xdmp:exists()可能是做出該決定的最快方法。如果您打算搜索文檔,那麼Search API並不是真正的過度殺手,因爲它提供了優化的分頁搜索以及其他功能 - 爲什麼重新發明這個輪子? – wst

回答

2

你的分析是正確的:

大概是因爲它不必每個文檔加載順序,檢查它是否是正確的類型和迭代,直到其找到$ fromCount NS:實體來說它甚至開始建立響應

通常的答案是cts:search加上unfiltered選項。您發現xdmp:directory速度更快,但即使比例較小,您仍應該能夠將分頁時間測量爲O(n)。見http://docs.marklogic.com/guide/performance/unfiltered#chapter - 基本上數據庫是防止返回誤報,除非你不告訴它。

另一種方法可能是使用cts:uris及其limit選項,但這可能需要根據起始值而不是頁數來管理分頁狀態。例如,如果頁面1上的最後一個項目是「cat」,則在爲下一頁調用cts:uris時,將使用「cat」作爲arg2。您仍然可以使用分頁開始 - 停止值。那仍然是O(n) - 但規模要小得多。