Производительность XQuery - неупорядоченный ответ? - PullRequest
2 голосов
/ 16 сентября 2011

У меня есть вопрос о производительности XQuery, надеюсь, кто-нибудь может помочь с этим.

Приведенный ниже код работает нормально, но я хотел бы улучшить производительность, если это возможно.Что он делает, так это ... - получает все отдельные значения атрибута prodname, найденного в совпадениях, - определяет, сколько раз каждое отдельное значение встречается в совпадениях - возвращает эти отдельные значения в порядке вместе с суммой для каждого

Иногда у меня до 12000 элементов в $ hit, поэтому весь процесс может занять некоторое время (в любом случае, дольше, чем хотелось бы).

Я читал, что использование неупорядоченных выражений / функций можетиметь значительное улучшение производительности.Итак, мой вопрос: есть ли способ улучшить производительность кода ниже - используя неупорядоченный или каким-либо другим способом - и какие изменения в коде должны быть сделаны?Мне все еще нужно было бы сохранить строку "order by $ 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 ]

2 голосов
/ 16 сентября 2011

Оптимизаторы XQuery сильно различаются от одного продукта к другому, и методы повышения производительности на одном продукте могут сильно отличаться от методов на другом. Поэтому невозможно ответить на этот вопрос, не зная (а), каким продуктом вы пользуетесь, и (б) не имея достаточно подробных знаний об оптимизаторе этого продукта.

Я не вижу особой причины, по которой "неупорядоченный" должен способствовать выполнению этого запроса, но если вы хотите это выяснить, попробуйте и посмотрите.

Первое, что я хотел бы сделать, чтобы попытаться улучшить этот запрос, это указать значение $ hit / ancestor-or-self :: DOCUMENT (или, возможно, $ hit / ancestor-or-self :: DOCUMENT / @ prodname ) в переменную. Это может иметь значение для некоторых продуктов или нет.

К сожалению, XQuery 1.0 не дает вам другого способа написания групповых запросов, кроме этого стиля "вложенного цикла". Если вы не можете заставить его работать, рассмотрите возможность использования инструкции XSLT 2.0 xsl: for-each-group, которая с гораздо большей вероятностью будет эффективной, поскольку вы говорите именно то, что вам нужно, и просите только один проход по данным.

1 голос
/ 16 сентября 2011

По мнению Майкла, в 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, где гистограмма даты и все аспекты используют этот подход). Мы собрали ряд рекомендаций по кодированию в SearchAPI, который поставляется вместе с MarkLogic, чтобы сделать построение такого интерфейса декларативным - вы просто указываете аргументы в XML-документе, а XQuery записывает соответствующий код (аналогично приведенному выше примеру) и вы получаете обратно и полезную нагрузку XML.

...