2015-06-12 7 views
4

У меня есть база данных BaseX XML с одним небольшим XML-файлом. Эти файлы в основном состоят из двух структур. Один из них - PlatformCategory с 46 экземплярами, другой PlatformGenericType с 213 экземплярами.Оптимизация медленного запроса XQuery в BaseX

PlatformGenericType имеет ссылки на PlatformCategory в атрибуте href.

<PlatformGeneralType id="/plib/platformgeneraltypes/pgt1"> 
    <name>No statement</name> 
    <enum>NO_STATEMENT</enum> 
    <isOfPlatformCategory href="/plib/platformcategories/pc1"/> 
    <readOnly>true</readOnly> 
</PlatformGeneralType> 

<PlatformCategory id="/plib/platformcategories/pc1"> 
    <name>No statement</name> 
    <enum>NO_STATEMENT</enum> 
    <environment>AIR</environment> 
    <readOnly>true</readOnly> 
</PlatformCategory> 

Когда я выполняю следующий запрос, он занимает около шести секунд, чтобы получить результат:

//PlatformGeneralType[isOfPlatformCategory/@href=//PlatformCategory[environment="AIR"]/@id] 

Что я могу сделать, чтобы оптимизировать этот запрос?

Обратите внимание, что я побежал «оптимизировать все».

Обновление: Вопрос по предыдущему запросу, по-видимому, решен. Но когда я расширяю запрос со следующим, запрос занимает 44,28 секунды:

/PLib/PlatformSpecificTypes/PlatformSpecificType 
[isOfPlatformGeneralType/@href=/PLib/PlatformGeneralTypes/PlatformGeneralType 
    [isOfPlatformCategory/@href=/PLib/PlatformCategories/PlatformCategory 
     [environment='AIR']/@id]/@id] 

есть 8939 экземпляров PlatformSpecificType и его структура:

<PlatformSpecificTypes> 
    <PlatformSpecificType id="/plib/platformspecifictypes/DataShip.3"> 
     <name>Meko 360H2</name> 
     <lethalityLevel>LOW</lethalityLevel> 
     <isOfPlatformGeneralType href="/plib/platformgeneraltypes/pgt62"/> 
     <ownedByCountry href="/plib/countries/10"/> 
    </PlatformSpecificType> 
</PlatformSpecificTypes> 

Его информация запроса:

Запрос: /PLib/PlatformSpecificTypes/PlatformSpecificType [isOfPlatformGeneralType/@ href =/PLib/PlatformGeneralTypes/PlatformGeneralType [isOfPlatformCategory/@ href =/PLib/PlatformCategories/PlatformCategory [environment = 'AIR']/@ id]/@ id] Результат: - Hit (s): 3642 Элементы - Обновлен: 0 товаров - Печатную: 2048 KB - Чтение Запирание: местный [command_plib] - Запись Блокировка: нет Хронометраж: - Синтаксический: 1,25 мс - Компиляция: 0,71 мс - Оценка: 44248,94 мс - Печать: 37.11 мс - Общее время: 44288.02 мс план запроса:

Свойства базы данных:

Database Properties 
Name: command_plib 
Size: 20247 KB 
Nodes: 781606 
Documents: 1 
Binaries: 0 
Timestamp: 2015-06-12-10-12-14 

Resource Properties 
Input Path: /home/sceran/Documents/PLIB/command_plib.xml 
Input Size: 21354 KB 
Timestamp: 2015-06-11-15-34-07 
Encoding: UTF-8 
CHOP: true 

Indexes 
Up-to-date: true 
TEXTINDEX: true 
ATTRINDEX: true 
FTINDEX: false 
LANGUAGE: English 
STEMMING: true 
CASESENS: true 
DIACRITICS: false 
STOPWORDS: 
UPDINDEX: false 
AUTOOPTIMIZE: false 
MAXCATS: 100 
MAXLEN: 96 

Запрос Информация:

Compiling: 
- rewriting descendant-or-self step(s) 
- rewriting descendant-or-self step(s) 
- converting descendant::*:PlatformGeneralType[(*:isOfPlatformCategory/@*:href = root()/descendant::*:PlatformCategory[(*:environment = "AIR")]/@*:id)] to child steps 
Query: 
//PlatformGeneralType[isOfPlatformCategory/@href=//PlatformCategory[environment="AIR"]/@id] 
Optimized Query: 
db:open-pre("command_plib",0)/*:PLib/*:PlatformGeneralTypes/*:PlatformGeneralType[(*:isOfPlatformCategory/@*:href = root()/descendant::*:PlatformCategory[(*:environment = "AIR")]/@*:id)] 
Result: 
- Hit(s): 55 Items 
- Updated: 0 Items 
- Printed: 12776 Bytes 
- Read Locking: local [command_plib] 
- Write Locking: none 
Timing: 
- Parsing: 0.55 ms 
- Compiling: 0.3 ms 
- Evaluating: 5786.29 ms 
- Printing: 1.0 ms 
- Total Time: 5788.15 ms 
Query plan: 
<QueryPlan compiled="true"> 
    <IterPath> 
    <DBNode name="command_plib" pre="0"/> 
    <IterStep axis="child" test="*:PLib"/> 
    <IterStep axis="child" test="*:PlatformGeneralTypes"/> 
    <IterStep axis="child" test="*:PlatformGeneralType"> 
     <CmpG op="="> 
     <CachedPath> 
      <IterStep axis="child" test="*:isOfPlatformCategory"/> 
      <IterStep axis="attribute" test="*:href"/> 
     </CachedPath> 
     <IterPath> 
      <Root/> 
      <IterStep axis="descendant" test="*:PlatformCategory"> 
      <CmpG op="="> 
       <CachedPath> 
       <IterStep axis="child" test="*:environment"/> 
       </CachedPath> 
       <Str value="AIR" type="xs:string"/> 
      </CmpG> 
      </IterStep> 
      <IterStep axis="attribute" test="*:id"/> 
     </IterPath> 
     </CmpG> 
    </IterStep> 
    </IterPath> 
</QueryPlan> 

Обновление два: Я подозреваю, структура PlatformSpecificTypes предотвращает индексацию. Мне интересно, изменил ли я его, как показано ниже, улучшит ли производительность запроса?

<PlatformSpecificTypes> 
    <PlatformSpecificType id="/plib/platformspecifictypes/DataShip.3"> 
     <name>Meko 360H2</name> 
     <lethalityLevel>LOW</lethalityLevel> 
     **<isOfPlatformGeneralType>/plib/platformgeneraltypes/pgt62 </isOfPlatformGeneralType>** 
     <ownedByCountry href="/plib/countries/10"/> 
    </PlatformSpecificType> 
</PlatformSpecificTypes> 

Update три: Я загрузил XML file in a gist, так что вы можете проверить его.

Теперь, когда я выполняю следующий запрос, я получаю около 28 секунд, чтобы получить результат.

/root/PlSpTys/PlSpTy[isOfPlGeTy/@href=/root/PlGeTys/PlGeTy[isOfPlCt/@href=/root/PlCts/PlCt[environment='AIR']/@id]/@id] 

Вот информация запроса:

Query: 
/root/PlSpTys/PlSpTy[isOfPlGeTy/@href=/root/PlGeTys/PlGeTy[isOfPlCt/@href=/root/PlCts/PlCt[environment='AIR']/@id]/@id] 
Result: 
- Hit(s): 3642 Items 
- Updated: 0 Items 
- Printed: 257 KB 
- Read Locking: local [Output6] 
- Write Locking: none 
Timing: 
- Parsing: 0.66 ms 
- Compiling: 0.34 ms 
- Evaluating: 28398.32 ms 
- Printing: 4.63 ms 
- Total Time: 28403.97 ms 
Query plan: 
<QueryPlan compiled="true"> 
    <IterPath> 
    <DBNode name="Output6" pre="0"/> 
    <IterStep axis="child" test="*:root"/> 
    <IterStep axis="child" test="*:PlSpTys"/> 
    <IterStep axis="child" test="*:PlSpTy"> 
     <CmpG op="="> 
     <CachedPath> 
      <IterStep axis="child" test="*:isOfPlGeTy"/> 
      <IterStep axis="attribute" test="*:href"/> 
     </CachedPath> 
     <IterPath> 
      <Root/> 
      <IterStep axis="child" test="*:root"/> 
      <IterStep axis="child" test="*:PlGeTys"/> 
      <IterStep axis="child" test="*:PlGeTy"> 
      <CmpG op="="> 
       <CachedPath> 
       <IterStep axis="child" test="*:isOfPlCt"/> 
       <IterStep axis="attribute" test="*:href"/> 
       </CachedPath> 
       <IterPath> 
       <Root/> 
       <IterStep axis="child" test="*:root"/> 
       <IterStep axis="child" test="*:PlCts"/> 
       <IterStep axis="child" test="*:PlCt"> 
        <CmpG op="="> 
        <CachedPath> 
         <IterStep axis="child" test="*:environment"/> 
        </CachedPath> 
        <Str value="AIR" type="xs:string"/> 
        </CmpG> 
       </IterStep> 
       <IterStep axis="attribute" test="*:id"/> 
       </IterPath> 
      </CmpG> 
      </IterStep> 
      <IterStep axis="attribute" test="*:id"/> 
     </IterPath> 
     </CmpG> 
    </IterStep> 
    </IterPath> 
</QueryPlan> 

Не могли бы вы мне помочь в оптимизации длительности запроса?

+0

Это похоже на довольно небольшой набор данных. Можете ли вы представить полный пример, например, в [gist] (https://gist.github.com/) (возможно, путем анонимной критической информации, если таковые имеются)? –

+0

На самом деле, в XML-файле существуют другие структуры, но не связанные со структурами, упомянутыми выше (PlatformGenericType, PlatformCategory). Чтобы предоставить пример, который вы хотите, я удалил другие структуры из файла XML. Но когда я выполняю запрос, я взял только 50,5 мс. Теперь, мне интересно, почему эти несвязанные структуры замедляют запрос? – user1587140

+0

Итак, есть больше данных внутри этого XML-файла? Сколько результатов для '// PlatformCategory [environment =" AIR "]/@ id'? Как долго эта часть запроса оценивается? Попробуйте заменить '//' абсолютным путем; по некоторым причинам BaseX не может оптимизировать для дочерних шагов. –

ответ

2

BaseX, похоже, не понимает, что он должен предварительно обработать «внутреннюю» часть статическим результатом, поэтому стоимость оценки составляет около O(n^2) вместо O(n).

Переформатирование вашего запроса (который занимает около 30 секунд на моей машине), чтобы лучше понять его, показывает, что вся правая сторона сравнения внутри первого предиката является статической, не зависящей от элемента PlSpTy проанализированы:

/root/PlSpTys/PlSpTy[ 
    isOfPlGeTy/@href=/root/PlGeTys/PlGeTy[ 
    isOfPlCt/@href=/root/PlCts/PlCt[ 
     environment='AIR' 
    ]/@id 
    ]/@id 
] 

Оценка этого занимает около 9ms на моей машине, которая не много, но может дорого обойтись, если бежал несколько раз. Подсчет количества элементов PlSpTy (count(/root/PlSpTys/PlSpTy)) показывает около 8939 таких элементов, поэтому оценка внутренней части стоит около 8939*9ms ~= 80s - что-то должно быть оптимизировано, но не все.

Что произойдет, если мы просто вытащим эту часть запроса и прекомпретируем его?

Расчет времени сокращается до 16 мс, из которых четвертый был использован для фактической печати результатов. Я открыл bug report requesting better optimization. (Обновление: some optimizations have been applied).

+0

Я также проверил ваше решение с реальными данными. Кажется, вы решили проблему. Спасибо за вашу помощь;) – user1587140

+0

не могли бы вы помочь мне по этой проблеме (http://stackoverflow.com/questions/30865291/basex-query-optimization-on-join)? – user1587140

+0

Некоторые оптимизации для этой проблемы [были включены в BaseX и вскоре должны быть включены в следующий снимок) (https://github.com/BaseXdb/basex/issues/1160#issuecomment-113525690). –

0

Последние snapshot of BaseX обеспечивает оптимизацию для вашего запроса: результаты выражения пути теперь будут кэшироваться, если они запрашиваются более одного раза. Оптимизация будет официально доступна с версией 8.2.2.