Memasukkan 10.00000 baris ke database sqlite3

Saya ingin memasukkan 10.00.000 baris ke dalam database, tetapi penyisipannya memakan waktu terlalu lama.

misalnya Sekarang saya mencobanya dengan 2055 baris dan butuh 3 menit untuk mengunggah data ini ke database.. dan kali ini terlalu banyak untuk 2055 entri.

Berikut cara saya memasukkan data ke dalam database:

      public void insert_database(Context context,String field1,String field2,String field3,String field4,String field5,String field6 ,String field7,String field8,String field9,String field10)
{

    try
    {
        //RayAllen_Database.beginTransaction();
        RayAllen_Database.execSQL(" insert or replace into "+ TableName_csv+" values( '"+field1+"' ,'"+field2+"','"+field3+"','"+field4+"','"+field5+"','"+field6+"','"+field7+"','"+field8+"','"+field9+"','"+field10+"');");


    }
    catch(Exception e)
    {
        //Log.i("Database Exception", "Exception");
        e.printStackTrace();
    }

}

dan di kelas lain bernama: Parsing Data: di sini saya mengurai file csv dan saat mengurai:

mencoba {

CSVReader reader=new CSVReader(new FileReader(filename));
String [] nextLine;

//create database
obj.create_database(context);
obj.OpenDatabase(context);
//reader.readNext();

while ((nextLine=reader.readNext())!=null)
{
          //here I am calling the insert_database function
    }
 }

jadi di sini Ini menguraikan baris satu per satu dan memanggil metode penyisipan untuk memasukkan entri ke dalam database..

Tapi ini memakan banyak waktu.. Bagaimana cara meningkatkan kinerja ini??


person Kanika    schedule 24.05.2012    source sumber
comment
Siapkan pernyataan sekali dan gunakan itu untuk semua penyisipan dalam satu sesi. Ini akan membuatnya lebih cepat. developer.android.com/reference/java/sql/PreparedStatement.html   -  person Sarwar Erfan    schedule 24.05.2012
comment
Apakah Anda punya alasan untuk melakukan penguraian CSV dan mengisi DB di perangkat? Apakah bisa dilakukan secara offline?   -  person Rajesh    schedule 24.05.2012
comment
Tapi saya mendapatkan file csv jadi saya perlu membacanya baris demi baris untuk menyimpannya ke dalam database   -  person Kanika    schedule 24.05.2012
comment
@SarwarErfan: Bisakah Anda memberi saya contoh PrepareStatement?   -  person Kanika    schedule 24.05.2012
comment
Memasukkan 10 juta baris adalah banyak yang dapat ditangani oleh ponsel cerdas sederhana... Di mana file CSV dibuat? Bisakah Anda menyalin/membuat database SQLite di server dan mengirim database yang siap dijalankan?   -  person Sam    schedule 24.05.2012
comment
Menurut saya, penyisipan atau penggantian sangat lambat, karena pada setiap baris harus memeriksa apakah Garis sudah ada, mungkin TANPA Indeks apa pun   -  person Rafael T    schedule 24.05.2012
comment
@Sam: Saya mendapatkan file csv melalui lampiran email kemudian saya menyimpan file itu ke sdcard, dan kemudian saya mulai membaca file melalui csv reader.. Tapi di sini perhatian utama saya adalah waktu..Bagaimana saya bisa meningkatkan kinerja seperti: nah saat upload 2000 data butuh waktu 3 menit untuk upload dan menurut saya itu terlalu banyak   -  person Kanika    schedule 24.05.2012
comment
Jika database dibangun pada prosesor yang lebih cepat (atau sekumpulan prosesor) katakanlah di server, maka setelah Anda mengunduh lampiran email tidak akan ada waktu pemrosesan.   -  person Sam    schedule 24.05.2012
comment
@RafaelT: Sekarang saya hanya menggunakan insert into dan masih perlu 3 menit untuk mengunggah file 2055 entri ini???   -  person Kanika    schedule 24.05.2012
comment
@Kanika: Silakan buka PC di mana Anda memiliki akses internet dan coba tautan ini. (Jika Anda memiliki internet, mungkin Anda akan mencarinya di Google terlebih dahulu) google .com/#q=android+siap+pernyataan+masukkan+contoh   -  person Sarwar Erfan    schedule 24.05.2012
comment
FFS: mulai gunakan transaksi dan kelompokkan sisipan Anda ke dalam bagian yang sesuai, misalnya. › 1000 menyisipkan pop. Ini jauh lebih cepat. Buat pernyataan yang sudah disiapkan dan gunakan kembali.   -  person Jens    schedule 24.05.2012


Jawaban (3)


Contoh singkat mengapa Anda harus melakukan hal yang benar dan bukan "salah". Ini diuji berjalan pada ICS 4.0.4, yang memiliki kinerja INSERT yang buruk.

Pertama, SQLiteOpenHelper sederhana yang membuat tabel dengan batasan UNIQUE pada kolom yang terkadang menyebabkan konflik.

class SimpleHelper extends SQLiteOpenHelper {
    // InsertHelpers are a really good idea - they format a prepared statement
    // for you automatically.
    InsertHelper mInsert;
    public SimpleHelper(Context context) {
        super(context, "tanika.db", null, 1);
    }
    @Override
    public void onOpen(SQLiteDatabase db) {
        super.onOpen(db);
        mInsert = new InsertHelper(db, "target");
    }
    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL("CREATE TABLE target (\n" +
                "_id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,\n" +
                "val1 TEXT NOT NULL,\n" +
                "val2 TEXT NOT NULL,\n" +
                "val3 TEXT NOT NULL,\n" +
                // Let's make one unique so we can get some juicy conflicts
                "val4 TEXT NOT NULL UNIQUE\n" +
                ")");
    }
    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    }
}

Dibundel dalam Activity lama kami menambahkan metode pengujian sederhana berikut:

long test(final int n) {
    long started = System.currentTimeMillis();
    ContentValues values = new ContentValues();

    for (int i = 0; i < n; i++) {
        values.clear();
        // Every 20th insert, generate a conflict in val4
        String val4 = String.valueOf(started + i);
        if (i % 20 == 0) {
            val4 = "conflict";
        }
        values.put("val1", "Value1");
        values.put("val2", "Value2");
        values.put("val3", "Value3");
        values.put("val4", val4);
        mHelper.mInsert.replace(values);
    }
    return System.currentTimeMillis() - started;
}

Seperti yang Anda lihat, ini akan menyebabkan konflik setiap tanggal 20 INSERT atau lebih. Memanggil InsertHelper#replace(..) menyebabkan helper menggunakan INSERT OR REPLACE pada konflik.

Sekarang, mari kita jalankan kode pengujian ini dengan & tanpa transaksi di sekitarnya.

class Test1 extends AsyncTask<Integer, Void, Long> {
    @Override
    protected Long doInBackground(Integer... params) {
        return test(params[0]);
    }
    @Override
    protected void onPostExecute(Long result) {
        System.out.println(getClass().getSimpleName() + " finished in " + result + "ms");
    }
}

class Test2 extends AsyncTask<Integer, Void, Long> {
    protected Long doInBackground(Integer... params) {
        SQLiteDatabase db = mHelper.getWritableDatabase();
        db.beginTransaction();
        long started = System.currentTimeMillis();
        try {
            test(params[0]);
            db.setTransactionSuccessful();
        } finally {
            db.endTransaction();
        }
        return System.currentTimeMillis() - started;
    }
    @Override
    protected void onPostExecute(Long result) {
        System.out.println(getClass().getSimpleName() + " finished in " + result + "ms");
    }
}

Semuanya dimulai seperti ini:

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    mHelper = new SimpleHelper(this);
    mHelper.getWritableDatabase(); // Forces the helper to initialize.
    new Test1().execute(2055);
    new Test2().execute(2055);
}

Dan hasilnya? Tanpa transaksi, INSERTs membutuhkan 41072ms. Dengan transaksi, mereka membutuhkan waktu 940 ms. Singkatnya, FFS, mulai gunakan InsertHelpers dan transaksi.

person Jens    schedule 24.05.2012
comment
InsertHelper tidak digunakan lagi, apakah ada cara lain untuk melakukan penyisipan db lebih cepat di Android. - person YLS; 27.03.2017

Anda dapat mengisi database Anda menggunakan alat offline dan kemudian mengimpornya saat Anda menginstal paket Anda. Anda dapat menyimpan database di kartu sd eksternal atau di folder aset aplikasi Anda.

Inilah cara saya melakukannya:

  1. Salin database aplikasi ke folder lokal menggunakan Android Debuger Bridge (adb) seperti ini: adb pull /data/data/<your application provider>/databases/yourdatbase.db C:/users/databases/yourdatbase.db.

  2. Hubungkan ke database SQLites C:/users/databases/yourdatbase.db dengan alat GUI/CLI favorit Anda dan lengkapi populasi 1 000 000 catatan Anda.

  3. Salin database yang telah diisi ke folder lingkungan pengembangan Android asset Anda.

  4. Sekarang uninstall aplikasi Anda dari perangkat untuk memastikan tidak ada database yang dibuat saat Anda menginstal pertama kali.

  5. Ubah kelas SQLiteHepler Anda sehingga ia memeriksa apakah ada database dan jika ada maka ia akan menggunakan database tersebut. Jika tidak ada database, Helper akan menyalin database dari folder aset Anda bersama dengan 1 000 000 catatan Anda. Inilah cara saya melakukannya:

    public class MyDatabaseHelper extends SQLiteOpenHelper {
    
        /*
            Other SQLiteOpenHelper declarations here ...
        */
    
        private static final String DATABASE_NAME   = "application.db";
        private static final String DB_PATH         = "/data/data/" + context.getPackageName() + "/databases/";
    
    
        /*
            Your SQLiteOpenHelper functions/procedures here ...
        */
    
        public boolean isDataBaseExist() {
    
            File dbFile     = new File(DB_PATH + DATABASE_NAME);
            return dbFile.exists();
        }
    
        public void copyDataBase(Context context) throws IOException {
    
            this.getReadableDatabase();
    
            InputStream inFile      = context.getResources().getAssets().open(DATABASE_NAME);
    
            // Path to the just created empty db
            String outFileName      = DB_PATH + DATABASE_NAME;
            OutputStream outFile    = new FileOutputStream(outFileName);
    
            // transfer bytes from the inputfile to the outputfile
            byte[] buffer = new byte[1024];
    
            int length;
    
            while ((length = inFile.read(buffer)) > 0) {
    
                outFile.write(buffer, 0, length);
    
            }
    
            // Close the streams
            outFile.flush();
            outFile.close();
            inFile.close();
        } 
    

Basis data ini akan dikompilasi dengan aplikasi Anda dan pada peluncuran pertama semua data akan ada di sana. Mungkin ada metode yang lebih sederhana, tapi saya harap ini membantu seseorang.

person Lukuluba    schedule 24.05.2012

Mempercepat operasi penyisipan sqlite melalui proses kasus serupa dan menunjukkan cara menggunakan transaksi untuk mengoptimalkan penyisipan.

person andyandy    schedule 24.05.2012