2012-04-07 31 views
0

我最近繼承了一個項目,其中一個sqlite數據庫存儲在用戶sdcard(僅限表格和列,沒有內容)。對於初始安裝(和隨後的數據更新),XML文件經由SAXParser的解析存儲它的內容的分貝列像這樣:Android + sqlite插入速度提升?

的SAXParser:

@Override 
    public void endElement(String uri, String localName, String qName) throws SAXException { 
      currentElement = false; 

      if (localName.equals("StoreID")) { 
       buffer.toString().trim(); 
       storeDetails.setStoreId(buffer.toString()); 
      } else if (localName.equals("StoreName")) { 
       buffer.toString().trim(); 
       storeDetails.setStoreName(buffer.toString()); 
      ... 

      } else if (localName.equals("StoreDescription")) { 
       buffer.toString().trim(); 
       storeDetails.setStoreDescription(buffer.toString()); 
       // when the final column is checked, call custom db helper method 
       dBHelper.addtoStoreDetail(storeDetails); 
      } 

      buffer = new StringBuffer(); 
    }   


    @Override 
    public void characters(char[] ch, int start, int length) throws SAXException { 
     if (currentElement) { 
      buffer.append(ch, start, length); 
     } 
    } 

DatabaseHelper:

// add to StoreDetails table 
    public void addtoStoreDetail(StoreDetails storeDetails) { 
     SQLiteDatabase database = null; 
     InsertHelper ih = null; 
     try { 
      database = getWritableDatabase(); 
      ih = new InsertHelper(database, "StoreDetails"); 

      // Get the numeric indexes for each of the columns that we're updating 
      final int idColumn = ih.getColumnIndex("_id"); 
      final int nameColumn = ih.getColumnIndex("StoreName"); 
      ... 
      final int descColumn = ih.getColumnIndex("StoreDescription"); 

      // Add the data for each column 
      ih.bind(idColumn, storeDetails.getStoreId()); 
      ih.bind(nameColumn, storeDetails.getStoreName()); 
      ... 
      ih.bind(descColumn, storeDetails.getStoreDescription()); 

      // Insert the row into the database. 
      ih.execute(); 
     } finally { 
      ih.close(); 
      safeCloseDataBase(database); 
     } 
    } 

加載的xml文檔長度超過6000行。當在設備上進行測試時,它會在中途停止插入(無錯誤),大約需要4-5分鐘。然而,在模擬器上,它運行速度相當快,大約20秒內將所有行寫入數據庫。我有打開db,添加數據,然後關閉時運行的日誌語句。在設備上運行時,LogCat輸出顯着較慢。有什麼我在這裏失蹤?爲什麼我的數據需要很長時間才能寫出來?我認爲改進後的InsertHelper會有所幫助,但不幸的是速度並不快。有人可以在這裏指出我的缺點嗎?

回答

1

我也指望InsertHelper明顯提高了速度,但是當我測試它時差別不是那麼大。

InsertHelper的強度仍然是多次插入,因爲它只編譯一次查詢。你這樣做的方式是爲每個插入聲明新的InsertHelper,這是繞過一次性編譯改進。嘗試使用同一個實例進行多次插入。

但是,我不認爲在慢速設備上6000+插入會在一分鐘內完成。

編輯還要確保你只取一次列索引,這會加快一點。將這些放置在批次插入的循環外部。

// Get the numeric indexes for each of the columns that we're updating 
final int idColumn = ih.getColumnIndex("_id"); 
final int nameColumn = ih.getColumnIndex("StoreName"); 
final int descColumn = ih.getColumnIndex("StoreDescription"); 
+0

感謝您的回覆。好吧,我改變了這個:dBHelper.addtoStoreDetail(storeDetails);到這個:arrayList.add(StoreDetails);當我遍歷列表來啓動InsertHelper舞蹈時,我的arrayList只包含最後一行......爲什麼「添加」只添加最後一行?一旦這樣排序,我應該回到正軌。 – worked 2012-04-07 23:17:07

+0

@worked:代碼在哪裏?沒有代碼,我無法幫助。 – 2012-04-08 07:58:32

0

當你像這樣進行批量插入時,你可能會更好地在DB助手中爲它設置一個特殊的操作。現在,每次插入一行時,都會打開和關閉與SQLite數據庫的連接,這會顯着降低您的速度。對於批處理過程,請將其設置爲可以維護整個導入作業的連接。我認爲在仿真器中速度更快的原因是,在運行時,仿真器完全存在於內存中 - 因此,儘管它有意降低CPU速度,但File IO速度要快得多。

0

除了連接數據庫只有一次可以在數據庫連接設置不要在批次結束提交每個插入後的變化,但只有一次?我試圖瀏覽Android開發文檔,但找不到確切的說明如何做到這一點(或者它已經這樣設置)。在其他平臺上將SQLite驅動程序的AutoCommit設置爲false,並且僅在批處理結束時進行提交才能顯着提高插入速度。