Getting more better performance with Update Batch Size in ado.net 2.0 Data Adapter

Komponen DataAdapter merupakan komponen yang digunakan sebagai "kurir" untuk commit semua perubahan data baik itu insert, update, delete yang terjadi di DataSet ke tabel yang ada di database. State untuk Insert,Update,Delete (IUD) diambil dari object dataset, karena setiap kali user melakukan perubahan di dataset saat itu juga row state versionnya berubah sesuai dengan aksi IUD.

Secara default di ado.net 1.x data adapter commit semua perubahan yang terjadi di dataset ke database untuk setiap record dengan masing masing statenya. Artinya kalau kita punya 1000 record di dataset dan semua record tsb datanya dirubah untuk masing-masing aksi IUD, maka 1000 kali *** data adapter melakukan round trip ke database untuk commit perubahan-perubahan tsb. Bayangkan kalau recordnya berjumlah puluhan ribu atau lebih dari itu.

Sebenarnya di ado.net 2.0 data adapter sudah menyediakan properti baru untuk menghindari jumlah round trip sebanyak jumlah perubahan record yang terjadi. Properti tsb yaitu UpdateBatchSize. Dengan pengaturan jumlah update batch size maka kita bisa tentukan jumlah record yang akan di update dalam satu waktu. Misalnya kalau kita punya 1000 record di data set dengan semua record tsb mempunyai state row versionnya change maka kita bisa tentukan misalnya dalam sekali round trip itu sekaligus commit perubahan untuk 100 record. Kalau kita bandingkan time processing nya maka perbedaannya bisa 3 x lipat lbh cepat.

Dalam artikel ini saya akan membuat contoh aplikasi sederhana untuk melakukan batch update size yang kita tentukan sendiri, secara default nilai batch update size nya yaitu 1. Asumsikan saya punya tabel TestPerformance dengan tiga kolom dan jumlah recordnya ada 1000. Kemudian tambahkan component SqlDataAdapter dari toolbox. Tools yang saya gunakan yaitu VS 2005, jadi anda harus tambahkan secara manual componentnya ke toolbox.

Untuk melihat proses yang dilakukan oleh data adapter ketika update semua perubahan ke database, kita gunakan event RowUpdating dan RowUpdated. Event RowUpdating terjadi sebelum RowUpdated. Dari event RowUpdated bisa dilihat pengaruh dari perubahan properti Update Batch Size. Untuk lebih jelasnya kita lihat code berikut (anda bisa download source filenya) :

Imports System.Data.SqlClient


Public Class batchUpdate

Private Sub batchUpdate_Load(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles MyBase.Load
Me.SqlDataAdapter1.Fill(Me.DsTestBatchUpdate.TestPerformance)
End Sub


Private Sub SqlDataAdapter1_RowUpdating(ByVal sender As Object, _
ByVal e As System.Data.SqlClient.SqlRowUpdatingEventArgs) _
Handles SqlDataAdapter1.RowUpdating
Console.WriteLine("Row value : " _
& e.Command.Parameters.Item(1).Value.ToString & " in RowUpdating")
End Sub


Private Sub SqlDataAdapter1_RowUpdated(ByVal sender As Object, _
ByVal e As System.Data.SqlClient.SqlRowUpdatedEventArgs) _
Handles SqlDataAdapter1.RowUpdated
Console.WriteLine("Row value : " _
& e.Row.Item(1).ToString & " in RowUpdated")
Console.WriteLine("Records Affected : " _
& e.RecordsAffected.ToString & " in RowUpdated")
End Sub


Private Sub btnUpdate_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles btnUpdate.Click
Me.SqlDataAdapter1.SelectCommand.UpdatedRowSource = UpdateRowSource.Both
Me.SqlDataAdapter1.UpdateCommand.UpdatedRowSource = UpdateRowSource.Both
Me.SqlDataAdapter1.InsertCommand.UpdatedRowSource = UpdateRowSource.Both
Me.SqlDataAdapter1.DeleteCommand.UpdatedRowSource = UpdateRowSource.Both
Me.SqlDataAdapter1.UpdateBatchSize = 1

Dim dtAwal, dtAkhir As Date
Dim tsDiff As New TimeSpan

dtAwal = Now
For i As Integer = 1 To 1000
Dim rowUpdate As DataRow = _
Me.DsTestBatchUpdate.TestPerformance.Rows.Find(i)
rowUpdate("col2") = i + 1
Next
Me.SqlDataAdapter1.Update(Me.DsTestBatchUpdate.TestPerformance.GetChanges)
dtAkhir = Now
tsDiff = dtAkhir.Subtract(dtAwal)
Console.WriteLine(tsDiff.TotalMilliseconds & ".ms")

Me.DataGrid1.DataSource = Nothing
Me.DataGrid1.DataSource = Me.DsTestBatchUpdate.TestPerformance
End Sub


Private Sub btnUpdateBatch_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles btnUpdateBatch.Click
Me.SqlDataAdapter1.SelectCommand.UpdatedRowSource = UpdateRowSource.None
Me.SqlDataAdapter1.UpdateCommand.UpdatedRowSource = UpdateRowSource.None
Me.SqlDataAdapter1.InsertCommand.UpdatedRowSource = UpdateRowSource.None
Me.SqlDataAdapter1.DeleteCommand.UpdatedRowSource = UpdateRowSource.None
Me.SqlDataAdapter1.UpdateBatchSize = 100

Dim dtAwal, dtAkhir As Date
Dim tsDiff As New TimeSpan

dtAwal = Now
For i As Integer = 1 To 1000
Dim rowUpdate As DataRow = _
Me.DsTestBatchUpdate.TestPerformance.Rows.Find(i)
rowUpdate("col2") = i + 1
Next
Me.SqlDataAdapter1.Update(Me.DsTestBatchUpdate.TestPerformance.GetChanges)
dtAkhir = Now
tsDiff = dtAkhir.Subtract(dtAwal)
Console.WriteLine(tsDiff.TotalMilliseconds & ".ms")

Me.DataGrid1.DataSource = Nothing
Me.DataGrid1.DataSource = Me.DsTestBatchUpdate.TestPerformance
End Sub

End Class

Simulasi code di atas dilakukan untuk tes performance update data. Tabel yang digunakan sudah berisi 1000 record, dan semua record saya update hanya untuk kolom "col2" saja. Update Batch Size nya saya set ke 100, artinya dala satu kali round trip ke database server akan melakukan updating sekaligus 100 record. Anda bisa lihat perbedaannya di console window, sekaligus melihat proses yang dilakukan oleh data adapter ketika melakukan updating data. Records Affected akan selalu bernilai 1 untuk setiap kali update dengan batch size 1, dan untuk update dengan menggunakan batch size 100 akan bernilai 100.

Berikut cuplikan dari output console window.

Untuk Batch Size = 1 :

Row value : 999 in RowUpdating
Row value : 999 in RowUpdated
Records Affected : 1 in RowUpdated
Row value : 1000 in RowUpdating
Row value : 1000 in RowUpdated
Records Affected : 1 in RowUpdated
Row value : 1001 in RowUpdating
Row value : 1001 in RowUpdated
Records Affected : 1 in RowUpdated
19898,6128.ms

Untuk Batch size 100 :

Row value : 997 in RowUpdating
Row value : 998 in RowUpdating
Row value : 999 in RowUpdating
Row value : 1000 in RowUpdating
Row value : 1001 in RowUpdating
Row value : 1001 in RowUpdated
Records Affected : 100 in RowUpdated
6389,1872.ms
Share this post: | | | |
Published Wednesday, May 02, 2007 3:38 AM by yulian
Filed under:

Comments

No Comments
Powered by Community Server (Commercial Edition), by Telligent Systems