2013-08-22 59 views
0

我是存在db的初學者。我正在通過Java構建一個XML文檔。我通過JAXB處理數據,然後通過插入更新插入到exists-db資源。目前我正在測試大約500個節點,並且在幾十個執行完成後,每插入一次最多需要10秒。我的XML具有以下一般結構。存在db更新插入很慢

<realestatedata> 
<agents> 
    <author id="1"> 
     <name>Author_A</name> 
    </author> 
    <author id="2"> 
     <name>Author_B</name> 
    </author> 
    <portal id="1"> 
     <name>Portal_A</name> 
    </portal> 
</agents> 
<artifacts> 
    <document id="1">    
     <latitude>51.37392</latitude> 
     <longitude>-0.00866</longitude> 
     <bathroom_number>1</bathroom_number> 
     <bedroom_number>3</bedroom_number> 
     <price>365000</price> 
    </document> 
    <theme id="1"> 
     <name>Garden</name> 
    </theme> 
    <place id="1"> 
     <name>BR4</name> 
     <location> 
      <lat>51.37392</lat> 
      <lon>-0.00866</lon> 
     </location> 
    </place> 
</artifacts> 
</realestatedata> 

爲了確保元件被放置在正確的順序中,我使用的嵌件更新下面的代碼,以便它的類型的一個新的記錄是第一一個或基於IDS相似的元件的端部被附加。

public void saveAuthor(Author author) { 
    XQueryService xQueryService = null; 
    CompiledExpression compiled = null; 
    int currentId = authorIdSequence.get(); 
    StringWriter authorXml = new StringWriter(); 
    try { 
     xQueryService = Utils.getXQeuryService(); 
     if (getAuthorByName(author.getName()) == null) { 
      author.setId(String.valueOf(authorIdSequence.incrementAndGet())); 
      marshaller.marshal(author, authorXml); 
      if(currentId == 0){ 
       compiled = xQueryService 
         .compile("update insert " + authorXml.toString() 
           + " into //agents"); 
      } 
      else{ 
       compiled = xQueryService 
         .compile("update insert " + authorXml.toString() 
           + " following //author[@id = '"+String.valueOf(currentId)+"']"); 
      }    
      xQueryService.execute(compiled); 
     } 

    } catch (XMLDBException e) { 
     e.printStackTrace(); 
    } catch (JAXBException e) { 
     e.printStackTrace(); 
    } 
} 

對文檔,地點等其他元素執行相同的方法。在幾次更新後,它變得非常緩慢。它開始需要長達十秒鐘來插入一條記錄。

只有我能找到的相關鏈接沒有回答。

http://sourceforge.net/mailarchive/forum.php?thread_name=s2s508bb1471004190430h8b42ee99o3f1835a9bc873d58%40mail.gmail.com&forum_name=exist-development

http://exist.2174344.n4.nabble.com/Slow-xquery-quot-update-insert-quot-performance-tt4657541.html#none

回答

2

的一點想法:當對大量節點上運行

  • 屬性過濾器([@id=…])可能會非常緩慢。考慮到您發佈的代碼需要eXist檢查以前插入的每位作者的@id,然後才能找到插入新代碼的正確位置。我可以想出幾種方法來解決這個問題:
    1. @id的範圍索引將大大加速事情。
    2. 使用@xml:id而不是@id可以讓你使用id(…),它會更快。這需要將您的ID更改爲唯一(例如「author_1」和「portal_1」)
    3. 如果您確實始終遞增您的@id值,則新節點將始終具有最大的@id。在這種情況下,following //author[last()]甚至into //agents將工作得很好。
  • 做很多小插入總是比做一個大插入慢。如果可能的話,延遲將新數據保存到eXist,直到你有一堆事情要做。
  • 確保您創建的XQueryService在完成之後能夠正確發佈。是Utils.getXQueryService()可能保留它不應該引用?
  • 確保你沒有不必要的複雜開銷。您可以在呼叫之間重複使用XQueryService嗎?如果getAuthorByName()正在查詢eXist,是否可以將它與更新查詢結合使用?你能否提供節點來插入通過變量綁定而不是查詢中的字面值,以便每次都可以重複使用相同的編譯查詢?

儘管如此,如果只有500個節點,單個插入10s是一個非常長的時間。在我的機器上使用未索引的「跟隨」語法在單個查詢中運行一批更新的快速測試可以在一半的時間內完成500次。很可能有更大的錯誤在你的問題中不明顯。