[ Željko @ 26.02.2004. 18:52 ] @

Recimo da imam datatable(ili dataset) objekat i prilikom sortiranja(ponovnog ucitavanja strane) ne bih da ponovo povlacim podatke iz baze. Da li je praksa da se takvi objekti (sa dosta podataka) cuvaju u session kolekciji? Ili to moze nekako drugacije da se izvede?

pozdrav Željko
[ degojs @ 26.02.2004. 21:17 ] @
Ne verujem da bi trebao da držiš data set na nivou sesije. Zašto misliš da je ponovno pozivanje baze gora stvar negp da server bude opterećen sa čuvanjem dataset-a u memoriji, pa još za sve korisnike (svaki sa svojim datasetom u sesiji)?
[ Dragi Tata @ 26.02.2004. 21:39 ] @
Pa u sesiji bi u stvari držao samo referencu na dataset, koji je i onako u memoriji. Zašto bi to bio problem?
[ degojs @ 26.02.2004. 21:43 ] @
Ako je veći dataset i ako je veći broj korisnika na sajtu, ne bi li to dovelo do bespotrebnog zauzeća memorije na serveru? Držanjem reference na dataset u sesiji obezbeđuješ da čitav objekt ostaje u memoriji, zar ne?
[ -zombie- @ 26.02.2004. 22:09 ] @
Citat:
Dragi Tata:
Pa u sesiji bi u stvari držao samo referencu na dataset, koji je i onako u memoriji. Zašto bi to bio problem?


pa ne bi ostao u memoriji, ako bi oslobodio referencu ka njemu, ne?

i kao što degojs reče: veliki dataset * puno korisnika == mrtav server. ;)

// edit: da, naravno.. nisam video degojsov post ;)
[ Dragi Tata @ 26.02.2004. 22:26 ] @
Ako bismo oslobodili referencu, onda bi objekat bio izbrisan iz memorije kad i ako GC nađe za shodno da ga pokupi. To znači da bi se u praksi (često?) dešavalo da moramo da pravimo nov dataset dok je onaj stari još negde u memoriji.
[ Dragi Tata @ 26.02.2004. 22:41 ] @
Mada, kad bolje razmislim, problem sa sesijom je što nikad ne znaš koliko će da traje, pa onda postaje nezgodno držati referencu na tako veliki objekat kao što je (ponekad) DataSet u Session-u.
[ Radudzoni @ 27.02.2004. 00:04 ] @
Ok, slazem se sa Tatom da referencu na Dataset ne treba drzati u sesiji, a pogotovo je ne treba unistiti, jer kao sto sama rec kaze ona ukazuje na objekat, pa bi se isti "izgubio"... ali covek, koliko sam ja razumeo, pita za slucaj sortiranja i ponovnog prikazivanja strane, i za takvu stvar mislim da je bolje tabelu drzati u objektu DataView pa njega sortirati, nego ga ponovo uzimati iz baze...

pozdrav
[ degojs @ 27.02.2004. 03:34 ] @
Sesija, po difoltu, je podešena na 20 minuta, čini mi se, što znači da ako korisnik ustane od računara, dataset svakako ostaje nedodirljiv za GC dok ne istekne tih 20 minuta.

Citat:
To znači da bi se u praksi (često?) dešavalo da moramo da pravimo nov dataset dok je onaj stari još negde u memoriji.


Vrlo često iz prostog razloga što GC ne trči svaki čas - ovo se odnosi i na desktop aplikacije. Praktično svaki put kada ti podaci zatrebaju (često je dovoljno jednom za jedno povezivanje na stranicu) kreiraš nove objekte iako su stari možda još uvek u memoriji, ali naravno nedostupni, pošto nema referenci koje pokazuju na njih. To što je stari dataset još uvek možda u memoriji je posao o kom GC treba da brine. Kao što desktop korisnik može da otvori i zatvori neku (Windows.Forms) formu 1000x ako hoće.

Mi ionako nemamo mogućnost da definitivno uklonimo objekt iz memorije kada hoćemo, zar ne?

Citat:
Ok, slazem se sa Tatom da referencu na Dataset ne treba drzati u sesiji, a pogotovo je ne treba unistiti, jer kao sto sama rec kaze ona ukazuje na objekat, pa bi se isti "izgubio"...


A gde ćeš je držati ako ne u sesiji, a hoćeš da ponovo ne vršiš upit pri novom pristupu stranici? Application ne dolazi u obzir, a onda ostaje samo još stranica (page scope). A to znači da se referenca uništava čim server pošalje stranicu klijentu.

Kreiranje novog objekta nije strašno (imamo čak i connection pooling, što rešava najčešći problem pri ovakvom radu), a ostavljanje istog bespotrebno u memoriji tokom čitave sesije može mnogo više da pogorša performanse servera. Čemu držati (potencijalno veliki) objekat u memoriji kad je konekcija sa korisnikom ionako zatvorena čim mu je poslat HTML kod za stranicu? Kada se slanje stranice završi, serveru (odnosno, GC-u) treba ostaviti slobodu da odradi svoj posao lepo, ako zatreba memorije.

U Session promenjivim se obično drži minimalan skup podataka: npr. dovoljno je da držiš int UserID koji dobiješ nakon što si verifikovao korisnika.
Svaki put kada ti zatrebaju podaci o korisniku na nekoj strani, jednostavno bi imao nešto poput:

Code:

int userID = System.Convert.ToInt32( Session["UserID"] );
CUser myUser = new CUser( userID );

this.labelImePrezime.Text = myUser.Fullname;
..


a tamo (u konstruktoru i drugim privatnim funkcijama) bi onda objekt izvršio povezivanje sa bazom, određeni upit i popunio svoje članove podatke. Ti podatke onda lepo čitaš preko svojstava i prikažeš na stranici kako ti već treba. Sad, ako objekt nije veliki, mogao bi da ga strpaš u Session, ali nije preporuka generalno. Čim su objekti kompleksiniji (npr. sadrže reference na druge objekte ili čak čitave kolekcije drugih objekata) znači da će i zauzeće memorije biti veće. Dobro, ne moraš u ovom slučaju da budeš toliko restriktivan i ograničiš se na samo UserID, možeš još neke podatke da ostaviš, ali treba imati mere - ne znam ni sam tačno šta bi bilo "mnogo".

Što se tiče podataka koji bi se prikazivali u DataGrid kontroli, možeš jednostavno napraviti public static funkcije koje će da vraćaju DataSet objekt. Ako je još potrebno i sortiranje, napravi to kao ulazni parametar funkcije. Npr.

Code:

DataSet podaci = CUser.GetUserSet( bool sortDescending ); // podaci o svim korisnicima
dataGrid1.DataSource = podaci;
dataGrid1.DataBind();


ili možeš čak da napraviš funkciju koja bi vraćala ArrayList CUser objekata, koji se takođe lepo prikazuju ud DataGridu (pošto ArrayList implementira IEnumerable), ali takva odluka je sad već vođena drugim stvarima (npr. klikom na link u tabeli, pozoveš odmah određenu funkciju tog CUser objekta ili šta već :).

I ovo pozivaš u recimo Form_Load svaki put (tj. verovatno NE kada je Page.IsPostBack == true).

Citat:
ali covek, koliko sam ja razumeo, pita za slucaj sortiranja i ponovnog prikazivanja strane, i za takvu stvar mislim da je bolje tabelu drzati u objektu DataView pa njega sortirati, nego ga ponovo uzimati iz baze...


Nije problem povezivati se sa bazom (connection pooling je tu), a baza ionako više voli da odrađuje neke upite nego da sedi i ne radi ništa po ceo dan :) Nikakvo toliko strašno usporenje neće se desiti zbog ovog - baza očas posla odradi upit, ne treba to toliko da brine (a ako se dešava, onda je verovatno vreme za generalku). Evo možemo da pitamo Gojka koliko upita ES vrši prosečno po jednoj stranici (dobro, ovde je broj značajno veći zbog toga što MySQL i ne podržava najbolje SQL92 pa mora da se vrši više jednostavnijih upita, ali opet - dođe na isto).
Ne treba zaboraviti da je slučaj različit od desktop aplikacije, gde će korisnik da verovatno ima jednu kopiju aplikacije pokrenutu, dok server mora da opslužuje n korisnika. U slučaju desktop aplikacije mi rasterećujemo server ako podatke držimo lokalno, a ovde bi ga opterećivali, više nego što ćemo da ga optrećujemo time što će za svako generisanje stranice morati da se ponovo spoji sa bazom. Nije to problem.

Svakako, za potrebe prikaza (sortirano ili ne) nema potrebe koristiti DataSet klasu, već DataReader, tako da onaj gore primer koji sam dao i nije najbolji.

I jedno i drugo ima prednosti i mana:
Citat:

This brought Dan (the DotNetMan) Green to the stage. Dan's from Monash.NET an Australian company specializing in training and consulting.

Datareader vs Datadapters:

The interesting subject of data readers vs data adapters and performance was then discussed. Here he said that it was horses for courses. Datareaders are really good for process that required a read once, like populating the business objects. He noted that datareaders follow the process of Connect, Retrieve, Process, Close and mentioned that if the processing of the data being read takes a long time then a datareader might not be suitable as resources on the database are held open until the processing is completed.

With DataAdapters the process is Connect, Retrieve, Close and Process. This means ithat the processing is done after the connection to the database is closed. Therefore, it is potentially more scalability. However, with any recommendation there was a note of caution in terms of size of data this is because dataset actually holds 2 copies of the data, the original data retrieved and the current state of the data.
[ janis @ 27.02.2004. 06:57 ] @

Zahvaljujem se svima na odgovorima.

pozdrav Željko
[ -zombie- @ 27.02.2004. 14:13 ] @
Citat:
degojs:
Evo možemo da pitamo Gojka koliko upita ES vrši prosečno po jednoj stranici


sumnjam da će gojko ovo videti, pa da odgovorim ja. ne znam tačno koliko je po stranici (nisam gledao sav kod), ali po onome što sam video, ima i nekoliko desetina sql upita (prilično neoptimizovano). ali zato znam da sql server prima par stotina (blizu hiljadu) upita u sekundi..

inače, ceo taj pristup oko keširanja podataka u sesiju (ili bilo gde drugde) je često naopak. zašto raditi posao db servera? pa on je taj koji treba da na najoptimalniji način barata podacima. ako nam neki trebaju često, onda sql server treba to da primeti, i da ih kešira u memoriji ili nešto slično..

samo kada su podaci isti za sve (ili bar za većinu) korisnika, a mi merenjem utvrdimo da je db server usko grlo, onda se može razmišljati o keširanju tih podataka negde drugde..
[ Željko @ 27.02.2004. 14:49 ] @

Citat:

inače, ceo taj pristup oko keširanja podataka u sesiju (ili bilo gde drugde) je često naopak. zašto raditi posao db servera?


Ne mislim da je problem u db serveru, naravno da on treba da radi svoj posao, pre mislim da je problem provuci veliku kolicinu podataka preko neta, i to raditi vise puta samo da bi se isti podaci prikazali na vise nacina (npr: 10 kolona u gridu i na svaku kolonu user klikne dva puta da bi sortirao podatke (ASC i DESC), to znaci 20 puta do baze i nazad sa sve podacima, kojih neka moze biti i punoooo).
To mi je bila glavna dilema, i zato sam postavio ovu temu.

pozdrav Željko
[ degojs @ 27.02.2004. 16:04 ] @
Pa, pošto se radi o ASP.NET aplikaciji ti i nemaš mnogo izbora: ili ćeš da teretiš dodatno web server sa držanjem podataka u memoriji ili ćeš da teretiš db server češćim upitima. Ovo drugo je, čini mi se, mnogo manje zlo. Eto, zombi ti kaže da ES izvršava po nekoliko stotina upita u sekundi.

Da se radi o desktop (Windows forms) aplikaciji onda bi mogao da podatke prevučeš na klijent pa ih tamo i ostaviš u memoriji sve dok korisnik ne završi rad sa njima - upravo zbog toga DataSet i jeste disconnected izvor podataka: DataAdapter se poveže na bazu, popuni DataSet i prekine konekciju. A ti onda lepo radiš sa podacima na lokalnoj mašini.

Citat:
pre mislim da je problem provuci veliku kolicinu podataka preko neta


Pazi, ako ima zaista mnogo podataka, koristi podelu po stranicama - korisniku je ionako nepregledno da mu izbaciš stranicu sa 200 zapisa - ko će se tu snaći? Ili ograniči skup podataka na one podatke koje korisnik treba zaista.

Pozdrav
[ -zombie- @ 27.02.2004. 16:21 ] @
može da se sortira i kod klijenta.. potraži na google:dhtml+table+sorting recimo.

evo i prvi rezultat, vrlo upotrebljiv, radi u svim browserima..

http://www.kryogenix.org/code/browser/sorttable/
[ Dragi Tata @ 27.02.2004. 16:38 ] @
Citat:
Željko:
to znaci 20 puta do baze i nazad sa sve podacima, kojih neka moze biti i punoooo).


U principu ne volim da solim pamet ljudima ako ne poznajem tačno problem sa kojim se sreću, međutim možda je problem u ovom "punooooo". Često je moguće smanjiti količinu podataka koja se dovlači iz baze. Koliko podataka možeš da prikažeš korisniku a da to bude čitljivo? Verovatno ne baš "punoooo".
[ degojs @ 27.02.2004. 17:06 ] @
Citat:
može da se sortira i kod klijenta..


E sad Željko ne može više da se žali ni na šta. Ja nikad nisam gledao dalje u JavaScript od programiranja alert-a sa porukom "Polje XXXXX je prazno. Molim unesite podatke." i dodeljivanje fokusa istom.
[ Željko @ 27.02.2004. 21:07 ] @

To sa "punooo" podataka je uzeto kao primer. Znam da se optimalnim dizajnom i paging-om podaci za prikaz svedu na racionalnu meru, medjutim iz iskustva znam da i malo podataka moze da bude problem ako je mreza losa, ali dobro da zavrsimo sa ovom temom, mislim da smo je "iscedili".

pozdrav Željko