2012-01-17 8 views
0

私はSAXパーサーを使用してXMLファイルをネットワーク上で解析しています。 解析中にデータをデータベースに追加したいので、INSERTクエリを使用してデータを追加します。しかし、各インサートには10​​〜15ミリ秒かかります。そして、私は解析と挿入にほぼ130秒かかっているほぼ150のレコードを持っています。 私はトランザクションで挿入クエリをラップしようとしましたが、それでも私は同じ時間を与えます。私は自分のコードを添付しています。私はそれを正しく解析しているのか、挿入トランザクションが間違っているのか分かりません。SAXパーサーの解析にデータベースの挿入に時間がかかります

XMLHandler.java

public class XMLHandler extends DefaultHandler { 

private static boolean inKey = false; 
private static boolean inCode = false; 
private static boolean inTitle = false; 
private static boolean inType = false; 
private static boolean inRoom = false; 
private static boolean inDescription = false; 
private static boolean inStart = false; 

private List List = new List(); 

public void startElement(String uri, String name, String qName, 
    Attributes atts) { 

if (name.trim().equals("key")) 
    inKey = true; 
else if (name.trim().equals("code")) 
    inCode = true; 
else if (name.trim().equals("title")) 
    inTitle = true; 
else if (name.trim().equals("type")) 
    inType = true; 
else if (name.trim().equals("room")) 
    inRoom = true; 
else if (name.trim().equals("description")) 
    inDescription = true; 
else if (name.trim().equals("start")) 
    inClassStart = true; 

} 

public void endElement(String uri, String name, String qName) 
    throws SAXException { 

if (name.trim().equals("key")) 
    inKey = false; 
else if (name.trim().equals("code")) 
    inCode = false; 
else if (name.trim().equals("title")) 
    inTitle = false; 
else if (name.trim().equals("type")) 
    inType = false; 
else if (name.trim().equals("room")) 
    inRoom = false; 
else if (name.trim().equals("description")) 
    inDescription = false; 
else if (name.trim().equals("start")) 
    inClassStart = false; 
} 

public void characters(char ch[], int start, int length) { 

String chars = (new String(ch).substring(start, start + length)); 

try { 
    if(inKey) 
      List.key = chars; 
    if(inCode) 
     List.code = chars; 
    if(inTitle) 
     List.title = chars; 
    if(inType) 
     List.type = chars; 
    if(inRoom) 
     List.room = chars; 
    if(inDescription) 
     List.description = chars; 
    if(inStart) 
     List.start = chars; 

    DB.insertFeed(List.key, List.code, List.title, List.type, List.room, List.description, List.start); 

} catch (Exception e) { 
    Log.e("NewsDroid", e.toString()); 
} 

} 

DatabaseManager.java

public void insertFeed(String key, String code, String title, String type, String room, String desc,String start) { 


    db.beginTransaction(); 
     try{ 
      String sql = "INSERT OR REPLACE INTO " + TEST+ "(KEY,CODE,TITLE, TYPE ,ROOM , DESCRIPTION, START) VALUES" + "(?,?,?,?,?,?,?);"; 
      Object [] bindArgs = new Object[]{key,code,title,type,room, desc,start}; 
      db.execSQL(sql, bindArgs);  
      db.setTransactionSuccessful(); 
} 
    catch (SQLException e){} 

    finally{ 

     db.endTransaction(); 
    } 
} 

答えて

3

あなたは(1行を毎回挿入されており、(db.openをやっているかもしれない)とdb.close)毎回。
これの代わりに "InsertHelper"を使用してみてください。
それは以下のように使用するには、粗例:

private void insertTweetSourcesInBulk(ArrayList tweetSources, boolean replace) { InsertHelper ih = new InsertHelper(db, TABLE_NAME_TWEET_SOURCE);

final int idIndex = ih.getColumnIndex(Audio._ID); 
    final int sequenceNumIndex = ih.getColumnIndex(TweetSource.SEQUENCE_NUM); 
    final int thumbnailUrlIndex = ih.getColumnIndex(TweetSource.THUMBNAIL_URL); 
    final int titleIndex = ih.getColumnIndex(TweetSource.TITLE); 

    for (TweetSource source : tweetSources) { 
     Logger.log(TAG, "Inserting id: " + source.getId()); 

     if (replace) { 
      ih.prepareForReplace(); 
     } else { 
      ih.prepareForInsert(); 
     } 

     ih.bind(idIndex, Integer.parseInt(source.getId())); 
     ih.bind(sequenceNumIndex, Float.parseFloat(source.getSequenceNum())); 
     ih.bind(thumbnailUrlIndex, source.getThumbnailUrl()); 
     ih.bind(titleIndex, source.getTitle()); 

     ih.execute(); 
    } 

    ih.close(); 
} 



+0

しかし、ArrayListで解析中に文字列を個別に追加すると、時間がかかるでしょうか? – Change

+0

はい、この方法では、同時に複数のレコードをデータベースに挿入するため、時間を節約できます。また、JSON形式で応答を受け取ることができれば、GSONまたはJACKSONパーサ(私はjacksonが好きです)を使って構文解析を高速化できます。 – akkilis

+0

あなたが私にもっとどのようにih.bind(idIndex、Integer.parseInt(source.getId()))を追加するかを説明できれば可能です。 getId()関数とは何を意味し、何をしますか? – Change

1

あなたの挿入文が右に見えます。データベースに適切なインデックスがありますか?各行がすでに存在するかどうかを判断する必要があるため、各INSERT文には既存の行の暗黙的な問合せが存在するためです。あなたのコードの "キー"が本当にプライマリキーである場合、それは暗黙的なインデックスを持っていますが、そうでない場合...これはあなたのトラブルを引き起こすかもしれません。

また、データベース操作が本質的に遅いことに注意してください。私が気付かないことの1つは、各INSERTが15ミリ秒かかると、どのように150個のINSERTが130秒かかるのでしょうか?

また、下記のakkilisの回答(InsertHelperについて)を見てください。すぐにあなたのDBに複数の行を挿入することができます。これにより、一時バッファにデータベースを格納する前に行を累積する必要があります。これはあまり難しくありません。

InsertHelperの詳細情報

http://developer.android.com/reference/android/database/DatabaseUtils.InsertHelper.html

+0

は間違いなくその部分を試してみましょう!私が今挿入している方法が狂っているからです。それは多くの時間がかかります! – Change

0

はINSERTごとに1つのトランザクションをしないでください。 INSERTのセット全体に対して1つのトランザクションを実行します。各トランザクションにはフラッシュI/Oが必要で、遅いです。

関連する問題