2011-09-15 15 views
2

我有一個XQuery性能問題,我希望有人可以提供幫助。XQuery性能 - 無序的答案?

下面的代碼工作正常,但如果可能的話我想提高性能。 它在做什麼... - 得到在命中 然後 中發現的prodname屬性的所有不同值 - 計算出每個不同值在匹配中發生的次數 - 按順序返回這些不同的值總共爲每個

我有時在$命中有多達12000個項目,所以整個過程可能需要一段時間(反正比我更喜歡它)。

我讀過使用無序表達式/函數可以顯着提高性能。 所以,我的問題是,是否有一種方法可以改善以下代碼的性能 - 使用無序或任何其他方式 - 以及需要進行哪些編碼更改? 我仍然需要「由$ d爲了」讓行,以保持不同值的字母順序對返回

let $tempResult := 
for $d in distinct-values($hits/ancestor-or-self::DOCUMENT/@prodname) 
    let $q := $hits/ancestor-or-self::DOCUMENT[@prodname = $d]  (: all the hits where prodname attribute has value of $d :) 
     order by $d 
     return <item zprodname="{$d}" zprodnamenum="{count($q)}"/> 

回答

2

XQuery的優化千差萬別從一個產品到另一個和技術來提高性能在一個產品上可能與另一個產品有很大不同。所以如果沒有(a)知道你使用的是什麼產品,並且(b)對該產品的優化器有相當詳細的知識,那麼你就不能回答這個問題。

我沒有看到爲什麼「無序」應該有助於查詢性能的特殊原因,但如果您想查明,請嘗試一下並查看。

我會試圖改進這個查詢的第一件事是將$ hits/ancestor-or-self :: DOCUMENT(或者$ hits/ancestor-or-self :: DOCUMENT/@ prodname)變成一個變量。這可能會對某些產品產生影響,或者可能不會。

不幸的是,XQuery 1.0除了這種「嵌套循環」風格外,沒有其他方式可以編寫分組查詢。如果您無法執行該操作,請考慮使用XSLT 2.0 xsl:for-each-group指令,該指令的效率更高,因爲您正在準確說出您想要的內容,只需要一次傳遞數據。

1

對於Michael的觀點,在MarkLogic中,這種方法是通過索引來解決這個問題,因爲您可能會獲得數百萬個物品的計數,並且基數可能非常低。下面是它看起來像MarkLogic擴展:

for $d in cts:element-attribute-values(xs:QName("your-element"),xs:QName("prodname"),(),"frequency-order") 
return <item zprodname="{$d}" zprodnamenum="{cts:frequency($d)}"/> 

其中「頻次」返回的項目在頻率的順序,但你可以省略的說法,並讓他們回到標順序。

這是一種常見的編碼模式,適用於需要多面導航的搜索應用程序(請參閱www.markmail.org中的基於XQuery的示例,其中日期直方圖和構面均使用此方法)。我們在與MarkLogic一起提供的SearchAPI中打包了一些編碼最佳實踐,以便構建這種接口聲明式 - 您只需使用XML文檔指定參數,然後XQuery編寫適當的代碼(類似於上面的示例)和你回來和XML負載。