Проблема сортировки XQuery - PullRequest
       15

Проблема сортировки XQuery

0 голосов
/ 28 октября 2011

Прямо сейчас у меня большие проблемы. Я новичок в XQuery, но сейчас я в проекте, использующем Xquery с использованием PHP и XSLT ..

В нашем проекте у нас большого нет. данные (это сайт со списком свойств), и я храню эти данные в Barkeley DB (XML DB). Проблема в том, что когда я ищу недвижимость, она занимает слишком много времени для получения результата. ORDER BY создает проблему (Query 1) .. без сортировки работает нормально (Query 2). Но для моего проекта нужна сортировка и она очень импотентна. Пожалуйста, проверьте мой запрос (Query1) и, пожалуйста, дайте мне решение как можно скорее. Ниже приведен запрос:

Query1:

        let $properties := (
            for $property in collection('bdb/properties.dbxml')/properties/property
                [ ( sale_price >=60000 and sale_price <=500000 ) and ( building_square_footage >=300 and building_square_footage <=3000 ) and ( bedrooms >=2 and bedrooms <=6 ) ]
            order by
                contains($property/mls_agent_id/text(), '505199') descending,
                matches($property/mls_office_id/text(), '^CBRR') ascending,
                $property/sale_price/number() descending
            return $property
        )

       let $properties := subsequence($properties,10,10) return <properties>{$properties}</properties>

Запрос 2:

    let $properties := (
       for $property in subsequence (
           collection('bdb/properties.dbxml')/properties/property
               [ ( sale_price >=60000 and sale_price <=500000 ) and ( building_square_footage >=300 and building_square_footage <=3000 ) and ( bedrooms >=2 and bedrooms <=6 ) ]
           , 1, 10)
        )
        descending return $property
    )  return <properties>{$properties}</properties>

Ответы [ 2 ]

0 голосов
/ 29 октября 2011

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

    let $properties := (
        for $property in collection('bdb/properties.dbxml')/properties/property
            [ ( sale_price >=60000 and sale_price <=500000 ) and ( building_square_footage >=300 and building_square_footage <=3000 ) and ( bedrooms >=2 and bedrooms <=6 ) and mls_agent_id = '505199']
        order by
            $property/sale_price/number() descending
        return $property,
        for $property in collection('bdb/properties.dbxml')/properties/property
            [ ( sale_price >=60000 and sale_price <=500000 ) and ( building_square_footage >=300 and building_square_footage <=3000 ) and ( bedrooms >=2 and bedrooms <=6 ) and (starts_with(office_id, 'CBRR') and not(mls_agent_id = '505199'))]
        order by
            $property/sale_price/number() descending
        return $property, 
        for $property in collection('bdb/properties.dbxml')/properties/property
            [ ( sale_price >=60000 and sale_price <=500000 ) and ( building_square_footage >=300 and building_square_footage <=3000 ) and ( bedrooms >=2 and bedrooms <=6 ) and not (starts_with(office_id, 'CBRR')]
        order by
            $property/sale_price/number() descending
        return $property
    )

   let $properties := subsequence($properties,10,10) return <properties>{$properties}</properties>

Другие вещи, которые могут быть полезны:

  • попробуйте использовать starts-with вместо matches - простое совпадение строк, вероятно, будет быстрее, чем регулярное выражение, и его легче оптимизировать
  • если разбить его на несколько вариантов выбора, как я делал выше, вы можете избежать второго или третьего выбора, если у вас уже выбрано достаточно элементов.
  • не выбирайте весь узел <property> только для удаления большей части того, что вы выбрали с помощью subsequence. Особенно при сортировке это, вероятно, означает большую пропускную способность памяти. Лучше выбрать только некоторый уникальный идентификатор, а затем использовать эти идентификаторы, чтобы позже получить остальную информацию о свойстве.

Например, вместо

let $properties:= for $property in collection('properties.dbxml')/properties/property[.....]
    return $property
let $properties := subsequence($properties,10,10)
return <properties>{$properties}</properties>

сделать вместо

let $property_ids:= for $property in collection('properties.dbxml')/properties/property[.....] 
    return $property/unique_id
return <properties>{
    for $id in subsequence($property_ids,10,10) return 
        collection('properties.dbxml')/properties/property[unique_id = $id]
}</properties>

Это означает, что последовательность в памяти будет набором небольших идентификаторов, а не больших узлов. Конечно, это означает, что для начала вам нужно иметь эти уникальные идентификаторы, но я подозреваю, что в базе данных MLS есть такие вещи.

0 голосов
/ 28 октября 2011

Не знаю, поможет ли это ... Но вы можете добиться большего успеха, попробовав альтернативные базы данных XML, которые предлагают более продвинутую оптимизацию запросов.Просто предположение, Ханнес

...