SqlDataSource e filtro dei dati, utilizzare WHERE o FilterExpression ?...

domenica 06 febbraio 2011 - 19.05
Tag Elenco Tags  C#  |  .NET 3.5  |  Visual Studio 2010  |  Visual Studio 2008  |  Visual Studio Express  |  SQL Server 2008 R2  |  SQL Server 2008  |  SQL Server 2005

andrestu Profilo | Expert

salve a tutti,
o una tabella che interrogo con un controllo SqlDataSource che per il momento non contiene molti dati ma in un futuro potrebbe contenerne parecchi e vorrei capire se per filtrare i risultati mi conviene utilizzare una query con il WHERE o la proprietà FilterExpression del controllo SqlDataSource ...
Se non erro la differenza sostanziale è che con la clausola WHERE recupero solo i dati interessati già filtrati invece con la FilterExpression i dati vengono filtrati sul dataview creato dal controllo, quindi nel primo caso il trasporto dei dati è minore però ad ogni cambio valori dei parametri di filtro dovrò effettuare una nuova richiesta al DB cosa che invece nel secondo caso non avviene perchè vengono filtrati sui dati già presenti... Voi che ne pensate???


Andrea Restucci - Web Programmer
www.andrearestucci.name
Download and try my FREE custom controls !!!

alx_81 Profilo | Guru

>salve a tutti,
ciao

>Voi che ne pensate???
non è per nulla un problema banale e devo ammettere che la risposta migliore è, a mio avviso, la famosa "dipende". Provo ad elencarti un po' di fattori che ti possono aiutare nella definitiva scelta.

- la select immessa nel datasource non deve mai essere un table scan
questo perchè una query che scansiona tutta la tabella, per antonomasia, non scala e, all'aumentare dei record perdi prestazioni. Quindi almeno un criterio che tenga i dati sempre "a pacchetti" ci vorrebbe. Ad esempio un intervallo di date, un range di id, una chiave particolare come l'utente (ovviamente dipende dal modello che hai). Se proprio deve essere una query enorme, magari prevedi un campo stato per cui non considerare più dei record (e magari fai un indice sullo stato stesso per alleggerire lo scan sull'indice stesso)

- se riesci a tenere il resultset snello, e quindi che scala, le scelte sono varie, tra cui pensare al caching lato applicazione, al caching lato server, oppure a chiamare il database ogni volta. Anche questo però dipende da quanto i dati che devi leggere cambiano, e soprattutto da quanto ti servono sincronizzati/aggiornati rispetto alla situazione sul database server. Se ti servono in tempo reale, non puoi farci nulla, devi tornare a database, magari con tecniche di aggregazione applicate al momento delle scritture nelle tabelle in questione (pensa ad una struttura di supporto che contiene gli aggregati o solo i record che ti serviranno, più snella e più veloce come accesso e lettura, meno i/o e meno cpu)

- se in multiutenza le query portano con sè risultati pressochè identici, allora pensa a non ripetere inutilmente le richieste e pensa seriamente al caching.

- la cosa migliore sarebbe il caching sul server (usando quello predefinito di .net, è buono, oppure creandoti strutture tue). Il caching dei dati garantirebbe la chiamata a db ogni "tot" tempo, in modo che il processo che interroga il database sia solo uno e non disturbi al di fuori della periodicità di interrogazione. Attenzione però, che questa tecnica porta con sè un piccolo problemino di eventuali desincronizzazioni, ma non solo. Ricorda che se ci sono eventi particolarmente importanti per cui la cache va invalidata, c'è da gestire anche questi casi.

- Fare caching sul cliente è un'opzione, ma diventa molto utile se dall'altra parte hai un fat client che tiene dentro di sè una parte di stato del server. Quindi il client dovrebbe essere "sempre acceso" e dovrebbe allocare tanta memoria quanta ne serve per il pacchetto dei dati che vuoi persistere.

Per ora non mi viene altro. Di certo, la FilterExpression potrebbe essere deleteria nel tuo caso, e, fino a che i dati non sono veramente molti rispetto a quanto può sopportare il tuo server (in base anche alle richieste), userei una bella condizione di where su cui magari hai fatto anche un bell'indice ben dimensionato e studiato.
--
Alessandro Alpi | SQL Server MVP
MCP|MCITP|MCTS|MCT

http://www.alessandroalpi.net
http://blogs.dotnethell.it/suxstellino
http://mvp.support.microsoft.com/profile/Alessandro.Alpi

andrestu Profilo | Expert

Grazie alx_81, come sempre professionalissimo.
Dalla tua risposta comprendo quanto le strade possano essere diversificate, e devo essere sincero che non sono molto esperto di gestione DB, a tal riguardo ti faccio ancora qualche domandina per comprendere meglio il meccanismo:

- Come si comporta il controllo SqlDataSource se faccio una query su una tabella senza implementare nessun tipo di filtraggio ? Ti crea un DataView (o altro oggetto che sia) che contiene tutti i record indipendentemente dal fatto che possano essere 1-100-100000 etc. ?
Se così fosse la vedo problematica con una grossa mole di dati, ci sarà sicuramente qualche meccanismo automatico che blocca il numero max di record...

- E' dificile implementare un indicizzazione? è un operazione che non ho mai fatto, da dove parto? è così importante in termini di efficenza e prestazioni? All'incirca su quale quantità di record la ritieni essenziale?

- Per quanto riguarda la cache lato server può essere considerata anche quella implementata automaticamente dal controllo SqlDataSource o ti riferisci ad altro tipo di cache?


Andrea Restucci - Web Programmer
www.andrearestucci.name
Download and try my FREE custom controls !!!

alx_81 Profilo | Guru

>Grazie alx_81, come sempre professionalissimo.
troppo gentile

>- Come si comporta il controllo SqlDataSource se faccio una query
>su una tabella senza implementare nessun tipo di filtraggio ?
fa una vera e propria chiamata 1:1 sul database. Puoi facilmente notarlo profilando con sql profiler la tua applicazione che usa sqldatasource.
La where è proprio quella lista di condizioni che ti permette di migliorare le performance della tua query, anche in base alle chiavi, agli indici eventualmente definiti, e al fatto che filtrando, come già dicevi tu, riduci il carico.

>Ti crea un DataView (o altro oggetto che sia) che contiene tutti
>i record indipendentemente dal fatto che possano essere 1-100-100000 etc. ?
il datasource non crea viste, tant'è che se non lo associ a nulla non vedi nulla .
diciamo che quando viene effettuato il binding, i controlli associati al source eseguono il metodo select del sql data source, appunto. Esso torna un IEnumerable, e quindi una lista generica di elementi. E torna proprio i record che quella select torna, non ci puoi fare nulla.

>Se così fosse la vedo problematica con una grossa mole di dati,
>ci sarà sicuramente qualche meccanismo automatico che blocca
>il numero max di record...
sì, ma il controllo dovrai farlo su database. Quindi prevedendo un TOP (N) per evitare che vengano letti più di N record. Oppure con la famosa where, che esclude i record da non considerare. Ed infine, quando hai i dati, se ancora vedi che gli hit a database sono tanti, caching, visto che anche il datasource te lo consente: http://msdn.microsoft.com/it-it/library/system.web.ui.webcontrols.sqldatasource.aspx#caching
>
>- E' dificile implementare un indicizzazione? è un operazione
>che non ho mai fatto, da dove parto? è così importante in termini
>di efficenza e prestazioni? All'incirca su quale quantità di
>record la ritieni essenziale?
sì, gli indici sono strutture essenziali per avere minore I/O, veloci letture, ottimizzazioni conseguenti. Implementarla non è difficile se si conoscono i tipi di interrogazioni che avrai sulle risorse che fanno parte di quelle query. Diciamo che se il database è tuo, saprai sempre quando le applicazioni accedono a particolari tabelle e come. Per modularizzare lo sviluppo inoltre, se sai di poter usare sql server, canalizzerei tutte le richieste verso stored procedure, in modo che anche i piani di esecuzione delle query in esse contenute siano messe nella cache di sql server (per evitare di riselezionare gli indici ad ogni esecuzione). Comunque prendi questa domanda per capire quanto un indice sia importante: "trovami il numero di telefono di una persona chiamata Alessandro Alpi nella provincia di Parma, ma in un elenco disordinato di righe". Senza indice e quindi senza ordinamento intrinseco, quanto ci metteresti? E come faresti ad essere sicuro che non esistano più persone con quel nome? Insomma, senza indice, sei costretto a fare scan di un librone
Non ragionerei in termini di numero di record, l'indicizzazione la farei sempre nelle ricerche che prima o poi saranno pesanti. E ragionerei a "tipo di operazioni" che vengono fatte sulle tabelle. Perchè se l'indice velocizza gli accessi in lettura, è anche vero che rallenta inserimenti, aggiornamenti (pensa alla necessità di riordinare le strutture). Quindi dovresti soffermarti anche sul tipo di utilizzo che si fa di ogni tabella in questione.

>- Per quanto riguarda la cache lato server può essere considerata
>anche quella implementata automaticamente dal controllo SqlDataSource
>o ti riferisci ad altro tipo di cache?
quella che ti ho linkato prima

--
Alessandro Alpi | SQL Server MVP
MCP|MCITP|MCTS|MCT

http://www.alessandroalpi.net
http://blogs.dotnethell.it/suxstellino
http://mvp.support.microsoft.com/profile/Alessandro.Alpi
Partecipa anche tu! Registrati!
Hai bisogno di aiuto ?
Perchè non ti registri subito?

Dopo esserti registrato potrai chiedere
aiuto sul nostro Forum oppure aiutare gli altri

Consulta le Stanze disponibili.

Registrati ora !
Copyright © dotNetHell.it 2002-2017
Running on Windows Server 2008 R2 Standard, SQL Server 2012 & ASP.NET 3.5