Learn the Rules, Break The Rules, and Create the New Ones...

Hi... My name is Rizky Prihanto. You can call me RQ, or Rizky either. I am currently living on Bandung, Indonesia. Had a lot of works and research about Enterprise Information Systems (majoring on education and e-governments). I have bunch of interests (some friends call it 'freakz') about MySQL Opensource Database and now I am one of the administrator of MySQL Indonesia User Group - the opensource community initialized by Sun Microsystems Indonesia.

My Company PT Cinox Media Insani, Bandung, Indonesia. I work here since 2008 and I take responsibility as Chief of Software Architect. My job is about planning, imaginating, fantasy-ing, concepting, and build the infrastructure of the new information systems (or app engines) which going to be implemented.

This blog This is my blog that represent my current opinion, research and experiences about anything in Software Engineering. Written since 2007 (actually) and has been vaccum for a lot of while. And now I wanna ressurrect this blog (optimistically) from the long-long-hibernation with something fresh and new ideas -- still about MySQL, software engineering, development, and may be something managerial here.

About the tagline I've learned the statement above from some paper written by Kent Beck about Extreme Programming (XP) methodology -- some sort of practical software development methods which have no boundaries. That's very inspiring me a lot. I have written some article on this blog that tell my interpretation about that statement here.

My Another Blogs I have classifying my blogs into some sort of genre. The blog that you read here right now is my primary blog that tell you (majoring) about IT stuff. But if you wanna look another side of me, you can visit here, here, here,or here. Hope it'll be interesting for some of you.

Credits I would thanks to Blogger for this great blog platform. Skinpress who designed this Wordpress template (which is bloggerized by Free Blogger Templates). My appreciate is also going to you who give your generously time for visiting my blog.

Optimasi ADODB Scripting

menurut kalian mana yang lebih efektif & efisien :

1) menulis ini di sebuah module :

Public con as new ADODB.Connection
Public rs as new ADODB.Recordset

trus bikin di Sub Main


Public Sub Main()
con.connectionstring = "...."
con.open
rs.activeconnection = con
...
dst...
...
End Sub

2) menulis ini di masing-masing form :

Private con as new ADODB.Connection
Private rs as new ADODB.Recordset

trus di form load :

Private Sub Form_Load()
con.connectionstring = "...."
con.open
rs.activeconnection = con
End Sub

n di form unload :

Private Sub Form_Unload()
rs.close
con.close
set rs = Nothing
set con = Nothing
End Sub


3) Nulis ini di masing-masing form :

Private con as new ADODB.Connection

trus object database dibuka di form load

Private Sub Form_Load()
con.connectionstring = "...."
con.open
End Sub

tapi object recordset baru dideklarasikan di procedure ketika dia dibutuhkan, seperti pas misalnya di CmdSave_Click()

Private Sub CmdSave_Click()
dim rs as new ADODB.Recordset
rs.activeconnection = con
rs.cursorlocation = adUseClient
rs.open "SELECT * FROM blabla"

... code n looping ditulis di sini...

rs.close
set rs = nothing
End Sub


menurut temen2 mana yang lebih efektif antara (1) (2) atau (3) ? ato ada yang punya gaya penulisan sendiri? dari sisi kecepatan gimana ?

oia, gaya create-object pas dibutuhin thox seperti di contoh nomor 3 itu aku baru nemuin. aku belum sempat benchmark... menurut kalian efisien nggak ? walau dari sisi typing mungkin agak banyak ngulang2 ngetik code...

ndox wrote :
----------------------------------------------------------------------------------------------
kalo aku mending pake yang nomer 1 aja. jadi kalo ada kesalahan cuma ngedit satu kali, gak usah berkali-kali. ngirit ngetik...
----------------------------------------------------------------------------------------------


TERNYATA...

cara paling efektif utk deklarasikan ADODB.Connection adalah di
public variabel di modules.

alasannya, klo kmu pasang di masing-masing form, ntar pas njalanin satu aplikasi mu dengan banyak form akan menghasilkan banyak connection ID. artinya, server akan menganggap banyak concurrent connection dalam satu waktu. dan apesnya, kadang ada DBMS yang (klo nggak disetting-setting) yang membatasi max_connection dengan angka yang kecil sekali. u know what I mean laah... ^_^ perwalian stiki beberapa semester yang lalu (bukan yg kemaren) sempet bermasalah dengan max-connection...

nggak percaya?
coba bikin aplikasi dengan 3 form, trus di masing2 form nya deklarasikan
Code:
Private db as new adodb.connection
. trus open 3 form tersebut. terserah dgn metode gimana... Dan klo kmu connect nya ke MySQL, coba buka di MySQL Administrator, di situ ada bagian "session" klo nggak salah... - dan lihatlah... padahal kmu hanya running 1 aplikasi, tp di MySQL Administrator tampak ada 3 user yang sedang connect... - BAYANGKAN klo aplikasi mu ini terdiri dari banyak form n banyak user yang menjalankannya. number of concurrent connection = 100 bisa jadi TEMBUS dalam waktu sekejap.

Gimana dengan ADODB.recordset?

cara paling safety utk mempergunakan object ADODB.recordset itu, TERNYATA kmu deklarasikan bukan di module (as public), ato di local form... tapi kmu construct di dalam masing2 procedure (sub/function).

alasannya?

variabel recordset itu merupakan variabel array of record untuk nampung output dari query select. Dia bisa menampung no result set, 1 record, 2, ato jutaan...

nah, klo misalnya kmu taroh di global, bayangkan, kapan variabel tampung itu akan di dispose dari memory? tentu ketika aplikasi kmu terminate... nah pas aplikasi sedang jalan n kmu nge-load recordset (query select) berkali2? tu alokasi memory masih nyangkut tuh sblum kmu exit dari aplikasimu.

ga percaya?

coba kmu bikin satu form, kasih grid (terserah), trus bikin query select yang kira2 menghasilkan output 1000 record. codenya kira2 gini deh :
Code:

'--- di module diasumsikan dah ada Public db as new adodb.connection
'--- n diasumsikan object db udah di open successfully
'--- nah skrg di salah satu form nih codenya :

Dim rs as new adodb.recordset, sSQL as string, i as integer

private sub command1_click()

listview1.listitems.clear
sSQL = "SELECT * FROM Customers"
if rs.state <> adStateClosed then rs.close
rs.open sSQL, db
if rs.recordcount > 0 then
for i = 1 to rs.recordcount
call IsiListView(listview1, rs(0),rs(1),rs(2),rs(3),rs(4))
rs.movenext
next i
end if
rs.close
end sub



yaa kira2 gtu lah Smile

klo kmu ngga punya database yang berukuran medium tsb, kmu bs pinjam database northwind bawaan nya access, sql server, ato bawaannya vb. search aja pake F3.. Very Happy

nah trus, sebelum kmu jalankan aplikasi mu itu..., sekalian jalanin juga Task Manager (ctrl+alt+del) n masuk ke tab processes. (tu window slalu always on top kan?). persiapan selesai, trus cb kmu jalanin aplikasi mu itu... tekan tombol Command1. trus liat di Task Manager. Memory Usage utk aplikasi mu nambah kan. trus coba kmu tekan lagi Command1 nya. berkali-kali kalo perlu... apa hasilnya ? mem usage bakal nambah terus n nambah terus....

baguskah itu? tentu tidak...

Oke-oke..., klo gtu, menurut Anda, mana cara yang ideal deh?

1. spt postingan ku di atas, gunakan Public declaration utk masang object ADODB.Connection... - taroh lah di salah satu module...

Code:
Public db as new ADODB.Connection


kmu langsung construct dgn ngasih keyword new jg nggak apapa...

2. lakukan peng-open-an connection cukup sekali pada Sub Main atau form load di form utama mu... (tentu stlh ngeset connectionstring yang bener n beberapa atribut macam cursorlocation, locktype, dll)...

Code:

Sub Main()
db.ConnectionString = "Provider=SQLOLEDB.1; blablabla"
db.CursorLocation = adUseClient
db.open
end sub


3. JANGAN LUPA close connection pada form utama di events unload. klo nggak, DBMS kadang juga nganggap koneksi masih aktif walo aplikasi mu udah ditutup (sebelum DBMS nge-ping smua client-nya apa masih bener2 aktif ato dalam kondisi idle)


Code:

Sub Form_Unload()
if db.state <> adStateClosed then db.close
set db = nothing
end sub


code set db = nothing ini adalah cara VB utk destroy object (destructor). tanpa ini, variabel db mu hanya dalam kondisi pause. ngga di free beneran...

4. Utk ngirim query yg ngga mbalikin resultset (INSERT/UPDATE/DELETE), pake object connection. Jangan pake recordset.

Code:

db.execute("INSERT INTO blablabla.....


5. utk ngirim query yang mbalikin resultset (SELECT), JUGA PAKAILAH OBJECT CONNECTION...

lho?
nggak salah tha iki ? Shocked

bener, bro!

utk ngirim query SELECT, alangkah baiknya klo kmu pake db.execute juga... utk nampungnya baru silakan pake recordset...

contoh codenya gini, biar jelas

Code:

Private sub Command1_click()
dim i as integer
dim rs as ADODB.recordset '--> perhatikan, ngga ada 'NEW' d sini
sSQL = "SELECT * FROM Customers"
set rs = db.execute(sSQL) '--> rs baru di-construct d sini..
if rs.recordcount > 0 then
for i = 1 to rs.recordcount
'retreive lah nilai rs ke variabel/grid/etc d sini....
rs.movenext
next i
end if
rs.close '--> tutup object recordset stlh smua nilainya dah
' dikasihkan ke variabel/grid/etc. di state ini, kita dah
' nggak butuh object recordset lagi...
set rs = nothing '--> stelah ditutup, buang lah jauh2 dari memory...
end sub


bgitu...
nilai efisiensinya di mana tuh?

object recordset itu dependen banget ama object connection. klo kmu pernah pake gaya rs.open, tentu kmu ga asing dengan syntax model gini :

rs.open sSQL, db

rs.close

ya kan?
apa sih parameter kedua dari rs.open setelah query? active connection...
artinya apa?

walaupun kmu pake rs.open, kmu tetep memanggil ulang properti n state dari object connection mu (db)... dengan syntax kmu spt itu, artinya kmu MENDATANGKAN dua object bersamaan. inisialisasi rs, dan memanggil kembali db... wuih,.. rame banget...

dengan model set rs = db.execute(sSQL), kronologinya bgini :
kmu kirimkan sql query SELECT mu via db.execute. stlh diproses sama DBMS, dia bakal mbalikin hasil query ke object db. yup. pada state ini, object db UDAH BERISI record-record hasil query SELECT mu itu tadi... tapi permasalahannya, record2 tsb belum di-parsing. blum di-array-kan. jadinya ngga bisa dipake utk di assign ke variabel... nah, utk memanfaatkan kumpulan data tsb, maka hasil .execute itu tadi di-assign ke object recordset... dan perintah SET rs = db.execute secara otomatis akan meng-construct object rs itu sendiri dengan resultset.. klo kmu dulu pernah belajar delphi d kampus (aku nggak) kmu mungkin pernah kebingungan pas manfaatin komponen ADOConnection1 yang musti kmu link-link kan dengan dataset segala... nah itu prinsipnya sama... ya kya gtu tadi kronologinya...

TRUS, setelah ini mau apa?

terus terang, saat ini *pas aku rombak* gaya pemrograman ADO ku dengan model teroptimasi kya gtuan, aplikasi gontortoise ku (ni proyek TA ku yang blon kelar2 dari dulu sampe skrg) jadi semakin lightweight. memory usage kecil di sisi client, beban server makin kecil, dan yang paling penting : aplikasiku yang terdiri dari 110 forms n 88 tabel jadi Wuzz Wuzz... (ngikut istilahnya JAY) walaupun aku developnya pake VB yang terkenal LEMOT executables-nya... (bilang pak Setiawan)

dna_psr_09 wrote :
----------------------------------------------------------------------------------------------
Klo aku mendink setiap kali db dibuka dan sudah selesai dipergunakan mending lagsung si tutup.... itung2 biar g buang2 memori.... kasian kalo kita develop di kompi yang lebih rendah spesifikasinya ....
trus jika digunakan untuk client server tidak terlalu memakan trafic yang terlalu banyak ...

so .....


bila

cn.open
...
...
...

Akhirannya ya
cn.close
Very Happy Cool
memang dalam pengetikan coding lebih panjang dan ribet .....
tapi jika kita memikirkan apa dampaknya jika telah di implementasikan di End User gimana Hayoooo .....

Kacian Kan ... Mad Mad


makasih ......

----------------------------------------------------------------------------------------------

dulu aku pernah jg model gtuan. object connection ku-declare-ku-open-n-ku-close di level routines (sub/function). tp akhirnya aku meninggalkan tu model krn NGGA BS KUPAKE utk apply transaction.. krn jika (misalnya) di command1_click aku bikin transaksi (cn.begintrans) n kuproses DML (insert update delete) trus ku tutup transaksi (if err then cn.rollbacktrans else cn.committrans), APA FUNGSINYA TU section transaction ? blass nggak ada Very Happy

yang kubicarakan di atas itu sbnrnya adalah optimasi penggunaan object recordset. krn klo kmu conn.open n rs.open thox ngga melakukan S.I.U.D., memory yang kepake "hampir" nggak ada n ngga pernah besar. kapan sih memory yang dipake AKAN menjadi besar? sebenarnya cuman pada 1 state : ketika kmu melakukan "SELECT". cuman itu... apalagi select yang mengembalikan 1juta record (hal yang pemborosan n percum tak bergun). di mana array of record itu ditampung nilainya klo nggak di sisi client? menggunakan adUseServer, jg bukan memecahkan masalah, krn traffic jadi padat. utk retreive satu baris record harus "minta" dulu ke server, trus diulangi utk baris-baris selanjutnya sampai 1 juta kali... Very Happy

operasi Insert Update Delete, yang nanganin kan server. yang mikir jg server. client cuman ngirim satu untaian SQL dan dia cuman nerima 1 nilai dari hasil pengiriman Insert/Update/Delete tsb : "SQLSTATE", dimana klo 0 dia artinya sukses di-insert/update/delete dan klo bukan 0 dia artinya error. misal :
020000 : terjadi duplicate key.
023000 : delete gagal karena ada data udah dipake di child tables.
042000 : kurang tanda petik satu (') tuh di query mu...

nah, berapa besar variabel yang ditampung rs ketika insert/update/delete ?
kecil banget.... 6byte! di sisi client, tuntutan resource yang besar itu HANYA ketika select. (ini termasuk execute stored procedures yang berisi hasil SELECT lho...)

jadi, pendeklarasian object connection di level routines, local form, global modules, hasilnya ngga akan terlalu kentara di sisi client. klo di level routines, efek di server 'hanya' ConnectionID nya cepet sekali meningkat. tp concurrent connectionnya tetep dianggap 0. sama server akan dianggap ngga ada satu pun client yang connect. lha gimana, wong baru akan nerima koneksi klo tombol di klik, n klo udah selesei mroses, koneksi akan diputus....
klo di level local form, baik connection ID maupun concurrent connectionnya akan meningkat, tergantung jumlah form yang kmu load... di mata server, koneksi yang dijalin dgn gaya beginian, akan tampak banyak user yang connect walo cuman 1 kenyataanya...
sedangkan klo di level modules, statistik connection akan lebih nyata... ada 1 user yang connect, ya ke-detect 1 di server...

berbeda jauh dengan pola pendeklarasian object recordset... di mana performa client akan sangat mempengaruhi performa aplikasi... yaa spt yang ku ulas di atas tuh...


CMIIWW,

Rizky Prihanto
http://www.linkar.co.id
http://www.software-arsitek.web.id

0 comments:

Posting Komentar