Modalità di ricerca in un archivio

lunedì 05 novembre 2012 - 13.44
Tag Elenco Tags  VB.NET  |  .NET 4.0  |  Windows Server 2008 R2  |  Visual Studio 2010  |  SQL Server 2008 R2

trinity Profilo | Guru

Salve ragazzi buongiorno,

allora vi spiego immediatamente la mia esigenza....un mio clinete mi ha chiesto di creare una banca dati stile rubrica nella quale vi sono i seguenti dati:

Vi elenco i campi del db che ho pensato di inserire

Nome_Cognome varchar
denominazione
categoria
subcategoria
tel
...
...

qui per l'inserimento non ci sono problemi il discorso nasce sulla ricerca in quanto il mio cliente vuole che nella pagina della ricerca ci siano solo due caselle ossia una nella quale si possono inserire per ricercare questi filtri: nome e cognome o denominazione o categoria sub-categoria e uan casella nella quale si inserisce la città....
Pertanto cerco consigli per avcere ottime prestazioni.....

Quindi la mia domanda è questa se nella prima casella di ricerca un utente digita il nome-cognome o solo la denominazione o solo la categoria o la sub-categoria come faccio a dire tramite sql che la parola scritta deve essere ricercata prima nel nome_cognome poi se non trova nulla legge la denominazione e se non torva nulla legge la categoria....secondo voi è giusto e logico così? Oppure la parola scritta per la ricerca deve essere ricercata sia nel campo nome_cognome, denominazione e categoria?

Faccio un esempio inventando dei dati di prova:

Supponiamo che ho i seguenti dati:

Nome_Cognome= Mario Rossi
Denominazione=campo vuoto
Categoria=Avvovato
Città=Roma

Nome_cognome=campo vuoto
Denominazione=Hotel Prova
Categoria=Alberghi
Città=Milano

In base a questi due esempi io nella prima casella di ricerca posso inserire Mario Rossi oppure solo Rossi oppure Hotel oppure Prova oppure alberghi..e mi deve ricercare i record che hanno la parola che sto ricercando.....

Ecco come potrei fare? Forse anche il db dovrei strutturalo in maniera diversa...Datemi un vostro parere e consiglio

Questo mio cliente sembra che vuole fare la ricerca come fosse le pagine gialle o google in pratica :(

Ciao e grazie
Cirillo Fabio
www.wondernet.biz
fabio@wondernet.biz
http://blogs.dotnethell.it/fabiocirillo/
http://wnetsoftware.blogspot.com

Gluck74 Profilo | Guru

>Questo mio cliente sembra che vuole fare la ricerca come fosse
>le pagine gialle o google in pratica :(
>
ed ha pure ragione!!!!

puoi benissimo fare una stored procedure che filtra per tutti i campi:
SELECT * FROM TABELLA WHERE PATINDEX('%' + @parametro + '%', Nominativo) >0 OR PATINDEX('%' + @parametro + '%', Categoria) >0 OR PATINDEX('%' + @parametro + '%', Azienda) >0
____________
http://glucolo.wordpress.com
Ricordati di utilizzare il tasto "Accetta" se i nostri consigli ti sono serviti a risolvere il problema.
È il modo per ringraziare chi ti ha aiutato.

trinity Profilo | Guru

Lo so i clienti hanno sempre ragione

Comunque la stored che mi ha passato permette di visualizzare tutti i record la cui key di ricerca rientra nei campi selezionati?

Ciao e grazie
Cirillo Fabio
www.wondernet.biz
fabio@wondernet.biz
http://blogs.dotnethell.it/fabiocirillo/
http://wnetsoftware.blogspot.com

Gluck74 Profilo | Guru

per ogni campo che vuoi includere nella ricerca, metti una riga in OR nella clausola WHERE, fatta così:

PATINDEX('%' + @parametro + '%', <nomecampo>) > 0

ciao
____________
http://glucolo.wordpress.com
Ricordati di utilizzare il tasto "Accetta" se i nostri consigli ti sono serviti a risolvere il problema.
È il modo per ringraziare chi ti ha aiutato.

trinity Profilo | Guru

Grazie
Cirillo Fabio
www.wondernet.biz
fabio@wondernet.biz
http://blogs.dotnethell.it/fabiocirillo/
http://wnetsoftware.blogspot.com

alx_81 Profilo | Guru

>ed ha pure ragione!!!!
ha ragione sì, ma funzionalmente.
Il tecnico deve pensare anche alle performances, e una query così fa solo ed esclusivamente PESANTISSIMI SCAN, che fino a che il db è piccolo, nessun problema, poi appena cresce un po' (e dipende dal server su cui gira) cade e comincia a dare timeout.
Credo che nel tuo caso trinity sia decisamente meglio pensare alle ricerche full text o a servizi non sql (vedi database documentali) che sono fatti apposta anche per ricerche di questo tipo.

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

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

trinity Profilo | Guru

Non ho mai utilizzato database che non siano sql server ed onestamente ora stavo utilizzando sql compact ce 4.0...ma la mole di dati sarà in futuro spero molta...il server remoto sono quelli di aruba perchè l'applicazione web girerà lì sopra...Te mi consigli il full text ma non l'ho mai utilizzato...che tipo di database dovrei mettere su, va ben sql ce 4.0 per iniziare e poi se la mole diventa elevata passo ad un sql server express 2008 o 2012 o sql server proprio...

Dammi se puoi qualche consiglio perchè il progetto sta partendo adesso e non vorrei fare qualche cavolata...semmai qualche esempio anche di full text

leggevo questa pagina:

http://www.webem-lab.it/programmazione/ricerca-fulltext-su-sql-server-2008-un-esempio-pratico

se non mi sbaglio forse a me serve utilizzare il metodo CONTAINS

anche se non ho capito molto la funzione del metodo: FREETEXT

e poi avendo a disposizione lo spazio che aruba mi da quando attivo un dominio mi sto spaventando quanto cita:

Il codice sorgente non è stato renderizzato qui
perchè non c'è sufficiente spazio.
Clicca qui per visualizzarlo in una nuova finestra

Domanda per me serve che su un campo, l'operatore scrive una parola e avviene la ricerca sia nella colonna nominativo, che nella colonna azienda che nella colonna categoria.....
1)Quindi dovrei creare 3 query full text per ogni colonna?
2)Il cliete può scrivere per esempio "avvocato" oppure "avv." oppure "avvocati" e la query deve ricercare tutti i record dove ci siano le parole che iniziano con 'avv' dato che è il minimo di ricerca

Il discorso è semplice io ho una tabella utenti la quale è in sostanza una tabella che funzionerà da rubrica...l'utente si registra e mette i classici dati..poi un altro utente può scegliere di ricercare in rubrica per nominativo o azienda o categoria o citta...tale parola da ricercare deve essere inserita in un'unico campo text al massimo posso utilizzare due campi text dove nel secondo ci indico la città....

adesso io ed il mio cliente speriamo che i record ossia gli utenti che si registrano siano migliaia, quindi se fossero 10.000 record sarei l'uomo è+ felice di sto mondo ma è possibile molto meno ma anche moltissimi di +...pertanto avendo descritto in questo post la mia situazione, è possibile che per ora posso appoggiarmi ai classici like sql e poi se un giorno dovessere i record aumentare allora passare al full text con un server privato...

ecco la mia tabella:

CREATE TABLE [Tab_utenti] ( [Id] int NOT NULL IDENTITY (1,1) , [Nominativo] nvarchar(100) NULL , [azienda] nvarchar(100) NULL , [Idcategoria] smallint NULL , [Categoria] nvarchar(100) NULL , [Idsubcategoria] smallint NULL , [Subcategoria] nvarchar(100) NULL , [Idregione] tinyint NULL , [Idprovincia] tinyint NULL , [Idcomune] smallint NULL , [Indirizzo] nvarchar(150) NULL , [Datanascita] datetime NULL , [Telufficio] nvarchar(15) NULL , [Faxufficio] nvarchar(15) NULL , [Cellulare] nvarchar(15) NULL , [Email] nvarchar(100) NULL , [Website] nvarchar(100) NULL , [Piva] nvarchar(11) NULL , [Codfiscale] nvarchar(16) NULL , [Facebook] nvarchar(100) NULL , [Twitter] nvarchar(100) NULL , [Skype] nvarchar(100) NULL , [Google] nvarchar(100) NULL , [Linkedin] nvarchar(100) NULL , [note] nvarchar(300) NULL , [Imageprofile] nvarchar(100) NULL , [Imageazienda] nvarchar(100) NULL , [Imagebackgroundcard] nvarchar(100) NULL , [Username] nvarchar(30) NULL , [password] nvarchar(30) NULL ); GO ALTER TABLE [Tab_utenti] ADD CONSTRAINT [PK_Tab_utenti] PRIMARY KEY ([Id]); GO CREATE INDEX [Keyricerca] ON [Tab_utenti] ([Nominativo] ASC); GO CREATE INDEX [Keyricerca1] ON [Tab_utenti] ([Denominazione_azienda] ASC); GO CREATE UNIQUE INDEX [Keyricerca10] ON [Tab_utenti] ([Username] ASC,[password] ASC); GO CREATE INDEX [Keyricerca2] ON [Tab_utenti] ([Categoria] ASC); GO CREATE INDEX [Keyricerca3] ON [Tab_utenti] ([Subcategoria] ASC); GO CREATE INDEX [Keyricerca4] ON [Tab_utenti] ([Categoria] ASC,[Subcategoria] ASC); GO CREATE INDEX [Keyricerca5] ON [Tab_utenti] ([Idregione] ASC); GO CREATE INDEX [Keyricerca6] ON [Tab_utenti] ([Idprovincia] ASC); GO CREATE INDEX [Keyricerca7] ON [Tab_utenti] ([Idcomune] ASC); GO CREATE INDEX [Keyricerca8] ON [Tab_utenti] ([Idregione] ASC,[Idprovincia] ASC,[Idcomune] ASC); GO CREATE INDEX [Keyricerca9] ON [Tab_utenti] ([Email] ASC); GO CREATE UNIQUE INDEX [UQ__Tab_utenti__0000000000000310] ON [Tab_utenti] ([Id] ASC); GO

Ciao e grazie
Cirillo Fabio
www.wondernet.biz
fabio@wondernet.biz
http://blogs.dotnethell.it/fabiocirillo/
http://wnetsoftware.blogspot.com

alx_81 Profilo | Guru

>Non ho mai utilizzato database che non siano sql server ed onestamente
>ora stavo utilizzando sql compact ce 4.0...ma la mole di dati
>sarà in futuro spero molta...il server remoto sono quelli di
>aruba perchè l'applicazione web girerà lì sopra...Te mi consigli
>il full text ma non l'ho mai utilizzato...che tipo di database
>dovrei mettere su, va ben sql ce 4.0 per iniziare e poi se la
>mole diventa elevata passo ad un sql server express 2008 o 2012
>o sql server proprio...
sinceramente non ho mai utilizzato CE e preferisco l'express in situazioni come la tua.
Se però il business cresce, non ha nemmeno molto senso che prendi un hosting, magari ha più senso avere un server da gestire su cui puoi licenziare anche prodotti più "corposi" (vedi le varie licenze di sql). Per fare le ricerche tipo "motore di ricerca", ci sono tanti strumenti non sql, ma se vuoi seguire la strada (del mio amato, per altro) SQL Server, ti conviene subito passare ad express e poi, se necessario, passare a licenze più avanzate e più dedicate a tipi di realtà impegnative.
In tal caso, ti servirà anche una tua "farm" per avere i tuoi server da gestire, ma prima il business deve giustificare la spesa. Ciò significa che con clienti che pagano poco, ovviamente puoi dare ricerche a tutto spiano, ma prima o poi scordati le performances. Quindi prevenire certi tipi di ricerca è sempre meglio, oppure limitarle alla vera utilità del funzionale. A volte considera che ti chiedono ricerche su tutto perché non sanno su cosa le faranno, quindi, forse è meglio capire se effettivamente la ricerca pesante è necessaria, seguendo e accompagnando il cliente. Considera che mi è capitato tante volte di dover fare dei report di decine di migliaia di righe, solo per dire di averli, ma per non vederli mai utilizzati. Certo, ci sono casi in cui ricerche di quel tipo sono necessarie, ma non è il ruolo del relazionale. Serve qualche strumento. Il full text è uno, ed è un servizio di supporto di sql server. Indicativamente però, senza campi ben definiti, è praticamente impossibile fare indici che ti diano velocità sulle query, specialmente se fai le like a destra e a sinistra (il contains per capirci).
Io propongo sempre:
- analizzare bene la funzionalità
- isolare i tipi di ricerca fondamentali
- ispezionare il modello per capire quali indici aiutano quel tipo di ricerca fondamentale
- indicizzare e scrivere l'applicazione sulla base di non dare troppa libertà
- se proprio questo non risolve il problema, servizi di supporto (database documentali, servizi di contorno per la ricerca full text)

sono certo che nel 90% dei casi non ti serve fare una ricerca su TUTTO, una ricerca su tutto, vuol dire che non sai cosa ricercare, almeno a priori.
Invece sono convinto che un cliente, se ben seguito e se ben "educato" possa dirti quello che gli serve, e se proprio quello che gli serve è tutto, deve pagare anche un pochino di più, perlomeno in termini di tempo e risorse.

>Dammi se puoi qualche consiglio perchè il progetto sta partendo
>adesso e non vorrei fare qualche cavolata...semmai qualche esempio
>anche di full text
Prima di tutto ci sarebbe da approfondire molto a lungo il discorso col tuo cliente, per isolare i tipi di ricerca che servono al lavoro che richiede.
Poi seguire i punti suddetti. Esempi di full text ne trovi finchè vuoi, ma prima di affrontare la problematica, cerca di capire fino a dove puoi fermarlo, molte volte il non mettere paletti, dà da una parte la libertà eccessiva al cliente di muoversi, e dall'altra crea problemi immani a te nel futuro.
Probabilmente potrebbe essere importante anche confrontarsi con realtà simili a quelle del tuo cliente per capire un po' come già sono stati risolti problemi. Ti faccio un esempio, facebook ha un bel motore di notifiche, se vai a vedere un po' su internet troverai anche l'approccio architetturale e di sviluppo che i dev hanno avuto. Questo è solo un esempio, ma se parliamo di realtà clienti nostri, basta vedere a che modello un particolare software può essere ricondotto. C'è veramente pieno di persone che seguono progetti per risolvere problemi che tutti hanno, per elencarti esempi:
- cache distribuite (appfabric di MS, memcached, ehcache, ..)
- dependency injection (ninject, unity, ..)
- log (log4net, ..)
- mock (nmock, rhino mock, ..)
- database documentali (mongodb, RavenDb, couchdb, ..)

insomma c'è veramente tanta carne al fuoco (free nella maggior parte dei casi) che ti aiuta a definire quella che è la scalabilità del tuo software.
Usate anche insieme, questi tool ti consentono di avere un relazionale, ma di sfruttare anche un layer i cui mettere qualcosa che ti consente proprio la scalabilità (cache per chiamate ripetute, balancing delle chiamate nel caso in cui il tuo traffico aumenti, ecc.).
Ora mi fermo. Il concetto è però semplice. Visto che sono andato ampiamente fuori dallo scope del post, vorrei tornarci dicendo. Fino a che regge, una soluzione a like a destra e sinistra va bene, ma un progetto con un database che può crescere su aruba mi sembra un presupposto un po' pericoloso ed instabile. Se il cliente paga ed il progetto è sostanzioso, dovresti forse iniziare a pensare di configurare server tuoi con installazioni sql tue, in modo da applicare, qualora necessario, anche il full text. Un buon link è il seguente:
http://technet.microsoft.com/en-us/library/cc721269(v=sql.100).aspx
parti da qui, e ce n'è un po'

>leggevo questa pagina:
>http://www.webem-lab.it/programmazione/ricerca-fulltext-su-sql-server-2008-un-esempio-pratico
>se non mi sbaglio forse a me serve utilizzare il metodo CONTAINS
devi studiare il servizio, ci sono funzioni per la ricerca full text che utilizzano algoritmi ottimizzati su una "base dati" che non vedi, ma che contiene le info per darti risultati ottimi con prestazioni ben diverse da quelle che potrebbe darti un relazionale facendo ricerche di quel tipo.
>anche se non ho capito molto la funzione del metodo: FREETEXT

>e poi avendo a disposizione lo spazio che aruba mi da quando
>attivo un dominio mi sto spaventando quanto cita:
aruba purtroppo non lo vedo nemmeno lontanamente un servizio da usare per un progetto molto impegnativo, se non spendendo molto.

>Domanda per me serve che su un campo, l'operatore scrive una
>parola e avviene la ricerca sia nella colonna nominativo, che
>nella colonna azienda che nella colonna categoria.....
>1)Quindi dovrei creare 3 query full text per ogni colonna?
>2)Il cliete può scrivere per esempio "avvocato" oppure "avv."
>oppure "avvocati" e la query deve ricercare tutti i record dove
>ci siano le parole che iniziano con 'avv' dato che è il minimo
>di ricerca
per questo prima devi studiare come funzionano e capire come applicarli nel tuo caso.
--
Alessandro Alpi | SQL Server MVP
MCP|MCITP|MCTS|MCT

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

trinity Profilo | Guru

Ciao Alessandro,
allora sei il progetto cresce in numero utenti ed in soldini è sicuro che prendo un server dedicato con licenze sql in modo tale da puntare anche ai full text...adesso devo partire e come mi consigli uso l'sql server di aruba intanto...allora il discorso per adesso è il seguente:

nella mia tabella io ho questi campi in cui il cliente può effettuare la ricerca:

nominativo
azienda
citta
categoria

adesso la citta la filtro con un altro campo e quindi paramtro specifico che si passa, gli altri campi verrano ricercati in una sola textbox..in pratica lui vuoi stile paginegialle.com se vedi ci sono due campi, nel primo ci scrivi il nome o l'azienda o la categoria e nel secondo la città e il risultato è che escono, se ci sono, record per quella determinata città ma che possono essere compresi negli altri campi..esempio

se voglio ricercare avv. rossi mario

la ricerca dovrà essere fatta nel campo nominativo e mi darà tutti i rossi mario, nel campo azienda e in questo caso nessun risultato e nel campo categoria che mi darà avvocato....
purtroppo le categori sono moltissime altrimenti mettevo se eranop massimo una ventina una bella combo con la categoria e quindi avevo maggiore filtro, invece le categorie sono oltre 70 e forse aumenteranno....ma ora che ci penso mi nasce il problema della lista categorie anche nell'inserimento in quanto in layout non posso caricare 70 record in una combo quando si aprirebbe uscirebbe una tendina lunghissima....devo vedere

Te cosa mi consigli?
Cirillo Fabio
www.wondernet.biz
fabio@wondernet.biz
http://blogs.dotnethell.it/fabiocirillo/
http://wnetsoftware.blogspot.com

Gluck74 Profilo | Guru

>Credo che nel tuo caso trinity sia decisamente meglio pensare
>alle ricerche full text o a servizi non sql (vedi database documentali)
>che sono fatti apposta anche per ricerche di questo tipo.

Ma secondo me state sparando ad una mosca con un bazuka!!!!!!!!!!!!!

Stiamo parlando di una tabella utenti, con 4 campi di ricerca messi in croce!!!!
Ho appena testato una mia tabella da 368.000 righe, facendo una query con il PATINDEX su 6 colonne, senza fare nessun tipo di accorgimento per le prestazioni, ovvero 6 PATINDEX schiantati nella WHERE e qualcuno usa pure CONVERT!!!

Nel caso peggiore ho ricevuto 47.318 righe in 10 secondi
Nel caso migliore ho ricevuto 63 righe in 3 secondi

Ora, considerando che TUTTI gli utenti (dalla notte dei tempi ad ora) del forum di HTML.it sono 176.000 (la metà della mia tabella), o il nostro amico vuole diventare miliardario (e lo spero per lui), o meglio che posi il bazuka.

Al massimo quello che puoi fare è una ricerca FULL-TEXT, ma niente di più.
Non comprarti una ferrari per andare dal panettiere dietro l'angolo!!!!
____________
http://glucolo.wordpress.com
Ricordati di utilizzare il tasto "Accetta" se i nostri consigli ti sono serviti a risolvere il problema.
È il modo per ringraziare chi ti ha aiutato.

alx_81 Profilo | Guru

>Nel caso peggiore ho ricevuto 47.318 righe in 10 secondi
>Nel caso migliore ho ricevuto 63 righe in 3 secondi
non so per te, ma per me già 500ms sono un'eternità..

>Ora, considerando che TUTTI gli utenti (dalla notte dei tempi
>ad ora) del forum di HTML.it sono 176.000 (la metà della mia
>tabella), o il nostro amico vuole diventare miliardario (e lo
>spero per lui), o meglio che posi il bazuka.
Se io ti dicessi che abbiamo 250mila utenti e se faccio join di un certo tipo una query come quella può metterci anche un minuto con un 48 core che mi dici?
Ogni cosa va contestualizzata, e poi, preferisco mettere in guardia dai possibili danni che, credimi, in tante aziende mi portano davanti (qualche riga in più ma poche) perchè il modello è messo molto male e gli indici non sono fattibili.. Credimi, la stai facendo un po' troppo facile, poi di certo io ho divagato, ma preferisco fare presente i veri problemi che si incontrano un po' in tutte le realtà.

>Al massimo quello che puoi fare è una ricerca FULL-TEXT, ma niente di più.
>Non comprarti una ferrari per andare dal panettiere dietro l'angolo!!!!
beh.. un documentale free non mi sembra un investimento impegnativo
Comunque capisco il tuo punto di vista, un forum è bello anche per quello
--
Alessandro Alpi | SQL Server MVP
MCP|MCITP|MCTS|MCT

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

trinity Profilo | Guru

Allora i db documentali free non li ho mai visti onestamente non sapevo neache della loro esistenza..ho sempre usato sql server e vorrei continuarlo a fare....

Delle join dovrò farle sicuramente diciamo che vincolo un pò il cliente con dei filtri che io gli richiedo x forza pertanto il like dovrei farlo solo sul campo nominativo e sul campo azienda...così dite che ottengo maggiore velocità nell'eseguire le query di ricerca?
Poi se il progetto aumenta e si trovano i soldini prendo un server dedicato un bel sql server 2008 o 2012 e con la full text miglioro le ricerche...Che ne dite?

ciao
Cirillo Fabio
www.wondernet.biz
fabio@wondernet.biz
http://blogs.dotnethell.it/fabiocirillo/
http://wnetsoftware.blogspot.com

alx_81 Profilo | Guru

>Allora i db documentali free non li ho mai visti onestamente
>non sapevo neache della loro esistenza..ho sempre usato sql server
>e vorrei continuarlo a fare....
ripeto, la mia non è una via da seguire per forza, è solo una considerazione che, tra l'altro, ho legato anche proprio a quanto paga il cliente per il progetto. Ogni cosa merita la sua attenzione, pur piccola che sia. Quindi capisco perfettamente il tuo approccio. Rimaniamo su sql server, ma se sei dotato della curiosità che ogni programmatore dovrebbe a mio avviso avere, nel tempo libero, guarda un po' di cosa si tratta.

>Delle join dovrò farle sicuramente diciamo che vincolo un pò
>il cliente con dei filtri che io gli richiedo x forza pertanto
>il like dovrei farlo solo sul campo nominativo e sul campo azienda...così
>dite che ottengo maggiore velocità nell'eseguire le query di ricerca?
secondo me dovresti impedire le contains. Se fossi in te userei uno Starts with (inizia per) che ti consente di usare appieno l'indice. Una cosa tipo:
LIKE parameter + %
ma non
% + parameter + %, che non performa benissimo, anzi, garantisce scan.

se riesci a strappare un inizia per, sei già ad ottimo punto e puoi usare la like senza problemi con indici opportunamente disegnati.
altrimenti puoi pensare agli algoritmi di distanza:
http://www.sqlteam.com/forums/topic.asp?TOPIC_ID=51540
che è quello che ti consente di fare ricerca per stringhe simili..

Se le righe non sono molte, puoi anche pensare di interrogare sql server solo per aggiornare una cache e poi querare la cache direttamente nel livello di biz della tua applicazione, in questo modo, in un futuro scalerai senz'altro di più.

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

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

Gluck74 Profilo | Guru

Sono pienamente d'accordo con il tuo punto di vista.
Stavo facendo una considerazione viste le info (soldini e contesto) date dal nostro amico. Se avevano in mente di mettere il loro progetto su aruba, probabilmente o hanno sbagliato completamente tutto, oppure (secondo me) il target è quello più vicino ad un contesto simile al mio.

>non so per te, ma per me già 500ms sono un'eternità..
sono d'accordo, anche per me 1,5 secondi sono inaccettabili, ma dipende anche dal contesto.
Ultimamente ho lavorato in contesti dove una query che ci mette 1,5 secondi va più che bene, (anche se usando tecniche come dici tu ci metterebbe 0,2 secondi), perché appunto non hanno possibilità in termini di tempo (sono convinto che è una scusa per nascondere incompetenza e scarsa voglia) ed anche di risorse. Ma tante volte comanda più il soldino che la ragione.

>Se io ti dicessi che abbiamo 250mila utenti e se faccio join di un certo tipo una query come quella può metterci anche un minuto con un 48 core che mi dici?
che dovresti provare a tirare su tutta la tabella e poi usare Linq 2 Object. Ci metteresti meno !!!!!!!!! ;-D
altro metodo in caso di join (lo dico per trinity così vede un'altra tecnica) è fare le ricerche sulle tabelle separate, prendere solo gli ID, e poi restituire i dati basandosi solo sugli ID, il tutto dentro una SP. Esempio:
Voglio tutti gli utenti che ... (parametri) e che hanno scritto nella loro scheda che .... (altri parametri)
DECLARE TABLE @IDutenti ( IDUtente int IDENTITY (1, 1) NOT NULL ) DECLARE TABLE @IDScheda ( IndexID int IDENTITY (1, 1) NOT NULL, IDUtente int not null ) INSERT INTO @IDutenti (IDUtente) SELECT DISTINCT CustomerID FROM [tblUtenti] c with (NOLOCK) WHERE <i PATHINDEX come esempio> INSERT INTO @IDScheda (IndexID, IDUtente) SELECT DISTINCT ISCheda, CustomerID FROM [tblChedaTecnica] c with (NOLOCK) WHERE <i PATHINDEX come esempio> SELECT C.* FROM @IDutenti U inner join @IDScheda S on U.IDUtente=S.IDUtente inner join tblUtenti C on C.IDUtente=U.IDUtente Order by ... ...
questa SP è molto più veloce di una normale query in join e i filtri applicati su tutta la join
Ma credo che a livello di SQL sai molto più esperto di me, quindi pongo questa soluzione sotto tuo esame per un commento.
Altra domanda su SQL, ma dentro una WHERE la PATINDEX è più performante di LIKE?? mi pare di si.

Detto questo, segnalo un bellissimo articolo per quanto riguarda gli algoritmi di distanza, dal quale ho preso spunto per creare un algoritmo che ho infilato in una function CLR:
http://www.catalysoft.com/articles/strikeamatch.html

Ciao, un saluto


____________
http://glucolo.wordpress.com
Ricordati di utilizzare il tasto "Accetta" se i nostri consigli ti sono serviti a risolvere il problema.
È il modo per ringraziare chi ti ha aiutato.

alx_81 Profilo | Guru

>Linq 2 Object. Ci metteresti meno !!!!!!!!! ;-D
eheheheh, già, concordo.. comunque, non mi succede.. vorrei sottolinearlo eh
Diciamo che volendo potrei ottenerlo

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

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

trinity Profilo | Guru

Aspetta Gluck74 fammi capire....io ho questa situazione devo creare una rubrica in pratica, quindi ho una tabella utenti dove si sono tutti i dati anagrafici, una tabella categoria ed una tabella comuni, la tabella categoria e comuni mi serve per le ricerche in quanto l'utente può ricercare un nominativo anche per categoria e comune....

pertanto supponiamo quanto segue:

CREATE TABLE [Tab_utenti] ( [Id] int NOT NULL IDENTITY (1,1) , [Nominativo] nvarchar(100) NULL , [Azienda] nvarchar(100) NULL , [Idcategoria] smallint NULL , [Idcomune] smallint NULL , [Indirizzo] nvarchar(150) NULL , [Datanascita] datetime NULL , [Telufficio] nvarchar(15) NULL , [Faxufficio] nvarchar(15) NULL , [Cellulare] nvarchar(15) NULL , [Email] nvarchar(100) NULL , [Website] nvarchar(100) NULL , [Piva] nvarchar(11) NULL , [Codfiscale] nvarchar(16) NULL , [Facebook] nvarchar(100) NULL , [Twitter] nvarchar(100) NULL , [Skype] nvarchar(100) NULL , [Google] nvarchar(100) NULL , [Linkedin] nvarchar(100) NULL , [note] nvarchar(300) NULL , [Username] nvarchar(30) NULL , [password] nvarchar(30) NULL ); GO ALTER TABLE [Tab_utenti] ADD CONSTRAINT [PK_Tab_utenti] PRIMARY KEY ([Id]); GO CREATE INDEX [Keyricerca] ON [Tab_utenti] ([Nominativo] ASC); GO CREATE INDEX [Keyricerca1] ON [Tab_utenti] ([Denominazione_azienda] ASC); GO CREATE UNIQUE INDEX [Keyricerca2] ON [Tab_utenti] ([Username] ASC,[password] ASC); GO CREATE INDEX [Keyricerca3] ON [Tab_utenti] ([Idcomune] ASC); GO CREATE INDEX [Keyricerca4] ON [Tab_utenti] ([idCategoria] ASC); GO CREATE TABLE [Tab_comuni] ( [Id] smallint NOT NULL , [Descrizione] nvarchar(100) NULL ); GO ALTER TABLE [Tab_comuni] ADD CONSTRAINT [PK_Tab_comuni] PRIMARY KEY ([Id]); GO CREATE UNIQUE INDEX [UQ__Tab_comuni__0000000000000031] ON [Tab_comuni] ([Id] ASC); GO CREATE TABLE [Tab_categorie] ( [Id] smallint NOT NULL , [Descrizione] nvarchar(200) NULL ); GO ALTER TABLE [Tab_categorie] ADD CONSTRAINT [PK_Tab_categorie] PRIMARY KEY ([Id]); GO CREATE UNIQUE INDEX [UQ__Tab_categorie__0000000000000050] ON [Tab_categorie] ([Id] ASC); GO

ecco queste sono le mie tabelle e le ricerche che devo fare sono:

1) login della persona quindi ricercare username e password
2) dopo il login prendere tutti i dati del record dell'utente connesso
3) ogni utente può eseguire una ricerca per trovare altri utenti e questa è quella + importante e deve essere veloce:
Ossia l'utente ha una form in cui vi sono 3 campi

campo1= (va inserita la parola da ricercare che può essere il nominativo o l'azienda o l'email
se poi non vogliono un'infinità di record allora possono anche rendere la ricerca più mirata compilando gli altri 2 campi ossia:
campo2= ccomune
campo3= categoria

ecco il quadro generale di quello che mi serve ed il tutto devo effettuare ricerche velocissime...adesso per ora ho parlato con il mio cliente e su aruba che vi è sql server 2008 partiamo con quello se la registrazione di utenti è notevole riuscirà ad ottenere dei fondi e quindi mireremo ad un server dedicato con sql server 2008 nostro privato e lì posso divertirmi...

Adesso che query o stored mi consigliate? calcolate che posso anche fare la ricerca nel campo1 scrivendo solo per esempio "Ros" e mi prende tutti i record con dove vi è dentro la parola "Ros" e forse dopo il colloquio con domani con il mio collega potrei anche come dice Ale utilizzare lo start with e quindi il like...

Chiedo il vostro parere/aiuto

ciao e soprattutto grazie delle vostra disponibilità


Cirillo Fabio
www.wondernet.biz
fabio@wondernet.biz
http://blogs.dotnethell.it/fabiocirillo/
http://wnetsoftware.blogspot.com

Gluck74 Profilo | Guru

Il vero esperto è Alex, io suggerisco e aspetto un consiglio suo.

Non farei per ora cataloghi fulltext giusto perché siete su aruba (che non so se te li fa fare).

fai una StoredProcedure simile al codice che ti ho fatto vedere.
esempio
CREATE PROC ... ... @strGenerale varhcar(100), @strComune varchar(100), @strCategoria varchar(100) ... ...
Il primo parametro lo usi per cercare gli ID degli utenti nella tabella utenti
Il secondo per cercare gli ID dei comuni nella tabella comuni
Il terzo per cercare gli ID delle categorie nella tabella categorie.
Un esempio di where:
WHERE PATINDEX(@strComune + '%', [Descrizione comune]) > 0 --nel caso di StarWith WHERE PATINDEX('%' + @strComune + '%', [Descrizione comune]) > 0 --nel caso di ricerca full
fatte le tre ricerche fai i join delle tre VarTable e sei pronto.

Se Alex conferma, dovrebbe essere più veloce in questo modo.
Poi se aruba ti fa fare i cataloghi fulltext, valuta se farli subito o magari dopo quando (e se) prenderete il vostro server.
(se il cliente non ha soldi per prendere un server, non ha nemmeno i soldi per pagarti del lavoro che farai per mettere su i cataloghi e/o DB documentali. Questo era il succo che dicevo ieri)

____________
http://glucolo.wordpress.com
Ricordati di utilizzare il tasto "Accetta" se i nostri consigli ti sono serviti a risolvere il problema.
È il modo per ringraziare chi ti ha aiutato.

trinity Profilo | Guru

Aspetta scusami ma andiamo in ordine perchè devo capire (perdonami se faccio tante domande) allora io avrei creato una stored del genere:

Il codice sorgente non è stato renderizzato qui
perchè non c'è sufficiente spazio.
Clicca qui per visualizzarlo in una nuova finestra

ecco come la io creerei...ora in base ai tuoi consigli ed in base alla stored che mi hai postato come dovrei modificare la mia (perchè onestamente nel post in cui hai scritto la stored non l'ho tanto capita :( )

Ciao
Cirillo Fabio
www.wondernet.biz
fabio@wondernet.biz
http://blogs.dotnethell.it/fabiocirillo/
http://wnetsoftware.blogspot.com

alx_81 Profilo | Guru

>ecco come la io creerei...ora in base ai tuoi consigli ed in
>base alla stored che mi hai postato come dovrei modificare la
>mia (perchè onestamente nel post in cui hai scritto la stored
>non l'ho tanto capita :( )
quel filtro fa l'and, quindi devono essere verificate tutte. E' quello che ti serve? Entriamo nel contesto di quello che serve a te, quindi utilizza quanto consigliato per risolvere il tuo problema reale.
ciao
--
Alessandro Alpi | SQL Server MVP
MCP|MCITP|MCTS|MCT

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

Gluck74 Profilo | Guru

quando dici che non ha i capito della mia SP, parli della Where, o della parte per trovare gli indici?

Per quanto riguarda la query che hai costruito ora, potrebbe anche andare bene, devi solo verificare le prestazioni.
inoltre, bisogna anche capire se le tre variabili, devono essere in concomitanza oppure no:
puoi fare una ricerca specificando solo un nominativo e non la categoria/città?
La ricerca avviene su un unico campo o su più campi?

Esempio:
se cerco "Rossi", "Rossi" viene cercato su quanti e quali campi?
"Rossi" può essere cercato senza specificare Categoria e/o Città?

Comunque ora siamo andati più su un problema SQL e non più ASP.NET.

ciao

____________
http://glucolo.wordpress.com
Ricordati di utilizzare il tasto "Accetta" se i nostri consigli ti sono serviti a risolvere il problema.
È il modo per ringraziare chi ti ha aiutato.

trinity Profilo | Guru

Allora prima di tutto voorei chiedere ad entrambi, dato che sti sta veramente passando al tema sql, se è possibile terminare ormai su questo post il mio problema...

Allora le tabelle che devo gestire l'ho postate nei post precedenti...io devo fare delle ricerche in questo modo:

per ora ho pensato solo di usare due textbox per la ricerca ma sto valutando l'ìinserimento o no di una terza (e a questo in base a quello che vi scriverò successivamente chiedo anche il vostro consiglio se adottarla oppure no)

ecco gli esempi ho due textbxo denominata txt_ricerca1 e txt_ricerca2. In txt_ricerca1 le persone che devo effettuare le ricerca ci possono scrivere nominativi di persone (o solo nome o solo cognome o entrambi) oppure nome di un'azienda oppure la categoria (es: avvocati o dentisti ecc...) nella txt_ricerca2 ci va messo il luogo di residenza. Il luogo di residenza non è obbligatorio ma ovviamente inserendolo farà si che la ricerca diventi + dettagliata e + veloce. Quindi i casi posso essere che si scriva nel campo txt_ricerca1 ma non nel campo txt_ricerca2 oppure in entrambi....

Supponiamo che nel db ci siano questi due record:

Rossi Mario avvovato Roma
Rossi franco avvocato Terracina
Rossi luigi dentista Milano
Verdi luisa ingegnere Firenze

Un utente può chiedere di ricercare solo i rossi, quindi scriverà nella casella txt_ricerca1 solo la parola rossi e gli darà i suoi risultati poi se vorrà specificare la zona scriverà il luogo di residenza nella casella txt_ricerca2. Oppure ci può essere il caso in cui l'utente vuole ricercare gli avvocati quindi scriverà nella casella txt_ricerca1 solo la parola avvocati oppure potrà specifiare che gli serve sapere gli avvocati di roma...ecc.
Ecco diciamo le varie possibili ipotesi...poi io inserirò la voce ricerca avanzata dove gli utenti potranno inserire maggiori filtri pe rla ricerca...
Adesso il mio problem aè creare una stored velocissima che mi dia i risultati in base alle varie possibilità di ricerca degli utenti...Da calcolare che nella tabella tab_utenti la categoria è salvata con l'id che fa riferimento alla chiave primaria della tabe_categoria e la stessa cosa per il comune (città) di ricerca.

Spero di aver detto tutto e spero che mi possiate dare una mano nel capire come procedere. e sopratttutto grazie ad entrambi :)

Ah! dimenticavo ricapitalando le colonne di ricerca della tabella tab_utenti saranno:

[Nominativo]
[Azienda]
[Idcategoria] ----descrizione
[Idcomune] ----descrizione

poi nella ricerca avanzata inserirò ovviamente qualche altro campo..ne parlerò con il mio cliente

Ciao e grazie di nuovo
Cirillo Fabio
www.wondernet.biz
fabio@wondernet.biz
http://blogs.dotnethell.it/fabiocirillo/
http://wnetsoftware.blogspot.com

trinity Profilo | Guru

Comunque della tua sp non ho capito la parte degli indici soprattutto...non è che potresti utilizzare i campi della mia tabella così capisco e meglio come hai ragione per la creazione della stored
Cirillo Fabio
www.wondernet.biz
fabio@wondernet.biz
http://blogs.dotnethell.it/fabiocirillo/
http://wnetsoftware.blogspot.com

alx_81 Profilo | Guru

>Comunque della tua sp non ho capito la parte degli indici soprattutto...non
>è che potresti utilizzare i campi della mia tabella così capisco
>e meglio come hai ragione per la creazione della stored
ciao,
a chi ti stai rivolgendo?
la sp è una cosa, gli indici un'altra.
Se stai chiedendo per la sp non saprei che dirti, abbiamo già detto tutto.
Se stai cercando di capire come muoverti con gli indici, dipende dai tuoi casi reali. Ma di certo dovrai conoscerli bene (soprattutto l'effetto che hanno, i vantaggi e gli svantaggi che portano) prima di muoverti.
--
Alessandro Alpi | SQL Server MVP
MCP|MCITP|MCTS|MCT

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

trinity Profilo | Guru

Mi riferivo a gluck74 che in una sua risposta ha scritto questo:

Il codice sorgente non è stato renderizzato qui
perchè non c'è sufficiente spazio.
Clicca qui per visualizzarlo in una nuova finestra

ecco non ho tanto capito la tecnica che ha usato in questa stored, la where si ma il discorso di fare la ricerca sugli ID e chiedevo se poteva fare un esempio di nuovo ma utilizznado i campi delle mie tabelle che ho postato interamente in uno degli ultimi post...così posso capire meglio la logica che ha utilizzato
Cirillo Fabio
www.wondernet.biz
fabio@wondernet.biz
http://blogs.dotnethell.it/fabiocirillo/
http://wnetsoftware.blogspot.com

alx_81 Profilo | Guru

Quindi per indici tu intendevi gli ID?
Io intendevo gli indici di sql server. Anche perchè gli id sono gli identificativi, e quindi questo mi ha portato fuori.
Vi lascio alla discussione.
ciao
--
Alessandro Alpi | SQL Server MVP
MCP|MCITP|MCTS|MCT

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

trinity Profilo | Guru

Ciao Gluck74,

appena hai tempo puoi spiegarmi la tua sp e la logica di come ricerchi gli indici?

Ciao
Cirillo Fabio
www.wondernet.biz
fabio@wondernet.biz
http://blogs.dotnethell.it/fabiocirillo/
http://wnetsoftware.blogspot.com

Gluck74 Profilo | Guru

giusto per verificare di non sparare con un bazooka ad una mosca, ho creato il tuo DB in locale:
tab_categorie -> 15 record
tab_comuni -> 8754 record (preso dal DB dei comuni italiani)
tab_utenti -> 35.000 record

quindi ho fatto questa query:
declare @search varchar(100) set @search = 'Hqzblr' select u.nominativo, u.azienda, c.descrizione from tab_utenti u inner join tab_comuni c on c.id=u.idcomune inner join tab_categorie ca on u.idcategoria=ca.id where c.descrizione like '%' + @search + '%' or ca.descrizione like '%' + @search + '%' or u.nominativo like '%' + @search + '%' or u.azienda like '%' + @search + '%'
il risultato è il seguente: [Result 1 / SQL execution time: 00.00.00.389 / Total time: 00.00.00.405]

se poi crei una SP, il risultato diveta più costante: [Result 1 / SQL execution time: 00.00.00.202 / Total time: 00.00.00.374]


Quello che volevo spiegarti con i post precedenti è questo:
invece di fare una where unica su tutti e 4 i campi, con una join tra tutte e tre le tabelle, puoi spezzare la ricerca sulle singole tabelle andando a cercare prima gli id su categorie, poi su comuni, poi su utenti. Alla fine hai trovato gli id corrispondenti agli utenti che ti servono, quindi fai vedere solo quei risultati.
ecco lo script:
Il codice sorgente non è stato renderizzato qui
perchè non c'è sufficiente spazio.
Clicca qui per visualizzarlo in una nuova finestra
come puoi vedere, faccio le ricerche nelle singole tabelle inmemoria (@com, @cat, @ut), poi nella tabella dei risultati filtro per indici, e non più sui campi.
il risultato è il seguente.
Versione 2
[Result 1 / SQL execution time: 00.00.00.233 / Total time: 00.00.00.249]

Nella versione 2, ho usato comunque una singola where ed il filtro "IN", che sappiamo non essere molto performante, specie se dovesse filtrare per parecchi id.
Ecco quindi un'altra miglioria: gli indici trovati per @cat e @com li metto in join con la tabella utenti per trovare altri indici
Il codice sorgente non è stato renderizzato qui
perchè non c'è sufficiente spazio.
Clicca qui per visualizzarlo in una nuova finestra
Versione 3
[Result 1 / SQL execution time: 00.00.00.218 / Total time: 00.00.00.233]


arriviamo poi a migliorare le prestazioni delle ricerche.
negli script precedenti, ho utilizzato il semplice like. Sappiamo che il "PATINDEX" è più performante, quindi sostituisco:
declare @cat table ( id int) declare @com table ( id int) declare @ut table ( id int) insert into @cat select id from tab_categorie where PATINDEX('%' + @search + '%', descrizione) >0 insert into @com select id from tab_comuni where PATINDEX('%' + @search + '%', descrizione) >0 insert into @ut select id from tab_utenti where PATINDEX('%' + @search + '%', Nominativo) >0 or PATINDEX('%' + @search + '%', Azienda) >0 insert into @ut select u.id from tab_utenti u inner join @com c on u.idcomune=c.id insert into @ut select u.id from tab_utenti u inner join @cat c on u.idcategoria=c.id select u.nominativo, u.azienda, c.descrizione as comune, ca.descrizione as categoria from tab_utenti u inner join tab_comuni c on c.id=u.idcomune inner join tab_categorie ca on u.idcategoria=ca.id inner join @ut x on x.id=u.id
Versione 4
[Result 1 / SQL execution time: 00.00.00.171 / Total time: 00.00.00.187]


Passando a 350.000 record nella tabella utenti, si arriva a questo risultato:
[Result 1 / SQL execution time: 00.00.01.575 / Total time: 00.00.02.027]
(26793 rows affected)

piuttosto che
[Result 1 / SQL execution time: 00.00.01.575 / Total time: 00.00.01.622]
(1742 rows affected)


vedi che siamo passati da circa mezzo secondo, a meno di 0,200
direi che sia un buon risultato, senza stare a creare FULL TEXT o addirittura cambiare database!!!

____________
http://glucolo.wordpress.com
Ricordati di utilizzare il tasto "Accetta" se i nostri consigli ti sono serviti a risolvere il problema.
È il modo per ringraziare chi ti ha aiutato.

trinity Profilo | Guru

Prima di tutto sei stato GRANDISSIMo mi hai dato una bellissima spiegazione e ho capito...una curiosità, questo codice ossia l'ultimo il + performante:

declare @cat table ( id int) declare @com table ( id int) declare @ut table ( id int) insert into @cat select id from tab_categorie where PATINDEX('%' + @search + '%', descrizione) >0 insert into @com select id from tab_comuni where PATINDEX('%' + @search + '%', descrizione) >0 insert into @ut select id from tab_utenti where PATINDEX('%' + @search + '%', Nominativo) >0 or PATINDEX('%' + @search + '%', Azienda) >0 insert into @ut select u.id from tab_utenti u inner join @com c on u.idcomune=c.id insert into @ut select u.id from tab_utenti u inner join @cat c on u.idcategoria=c.id select u.nominativo, u.azienda, c.descrizione as comune, ca.descrizione as categoria from tab_utenti u inner join tab_comuni c on c.id=u.idcomune inner join tab_categorie ca on u.idcategoria=ca.id inner join @ut x on x.id=u.id

se lo metto in una stored diventa ancora + veloce e migliore anche questo risultato? [Result 1 / SQL execution time: 00.00.00.171 / Total time: 00.00.00.187]

poi altra curiosità ma questo risultato:
Passando a 350.000 record nella tabella utenti, si arriva a questo risultato:
[Result 1 / SQL execution time: 00.00.01.575 / Total time: 00.00.02.027]
(26793 rows affected)

è su 350.000 record, invece questo:

piuttosto che
[Result 1 / SQL execution time: 00.00.01.575 / Total time: 00.00.01.622]
(1742 rows affected)

Ciao e grazie mille...

Per informazione andrò a creare la mia stored e poi te la posto x vedere se ho capito bene e se è scritta bene, ok?

ah piccolissima domanda stramba ma google come fa a ricercare così velocemente milioni di record? :D

Cirillo Fabio
www.wondernet.biz
fabio@wondernet.biz
http://blogs.dotnethell.it/fabiocirillo/
http://wnetsoftware.blogspot.com

Gluck74 Profilo | Guru

>Prima di tutto sei stato GRANDISSIMo mi hai dato una bellissima
>spiegazione e ho capito...una curiosità, questo codice ossia
>l'ultimo il + performante:
>se lo metto in una stored diventa ancora + veloce e migliore
>anche questo risultato? [Result 1 / SQL execution time: 00.00.00.171
>/ Total time: 00.00.00.187]
il codice che ho postato, io l'ho già provato dentro una stored, ci possono essere solo piccole variazioni che dipendono solo dal risultato

>
>poi altra curiosità ma questo risultato:
>Passando a 350.000 record nella tabella utenti, si arriva a questo
>risultato:
>[Result 1 / SQL execution time: 00.00.01.575 / Total time: 00.00.02.027]
>(26793 rows affected)
>
>è su 350.000 record, invece questo:
>
>piuttosto che
>[Result 1 / SQL execution time: 00.00.01.575 / Total time: 00.00.01.622]
>(1742 rows affected)
>

è lo stesso. sono 2 ricerche, ma la query è identica sulle stesse tabelle.
Ti volevo solo fare notare che la prima ha restituito 26.000 record, la seconda solo 1.700, ma il tempo di esecuzione non cambia.
hai solo un total time diverso solo perché vengono restituiti più record.


>
>ah piccolissima domanda stramba ma google come fa a ricercare
>così velocemente milioni di record? :D
e be, in questo caso si parla di cose ben diverse.
Prima di tutto il db centrale non è di certo relazionale, perché stiamo parlando di moli di dati ben diverse, inoltre anche architetturalmente ci sono grosse differenze. Ad esempio ci potrebbero essere dei DB satellite (anche relazionali) che fungono da cacheDB geografici.....
Anche una famosa azienda di consegne (giusto per parlare di una realtà vicina e italiana anche se non dico il nome) ad esempio, ha il DB centrale per lo smistamento della posta a Pontedera, mentre i clienti che accedono via web per vedere dove sta la spedizione, in verità interrogano un cacheDB satellite che sta a Milano

ciao e buon lavoro
____________
http://glucolo.wordpress.com
Ricordati di utilizzare il tasto "Accetta" se i nostri consigli ti sono serviti a risolvere il problema.
È il modo per ringraziare chi ti ha aiutato.

trinity Profilo | Guru

Ciao
con il cliente abbiamo parlato e si è arrivata alla conclusione che ci sarà solo un campo nel quale verrà salvato o il nominativo o il nome dell'azienda. Il campo si chiamerà utente, pertanto ecco la tabella aggiornata:

Il codice sorgente non è stato renderizzato qui
perchè non c'è sufficiente spazio.
Clicca qui per visualizzarlo in una nuova finestra



allora lato interfaccia utente vi saranno due textbox, nella prima si scriverà la parola da ricercare nella colonna utente o nella categoria, mentre nella seconda textbox si indicherà il comune...ovviamente il comune è facoltativo serve a ristringere solo la ricerca, pertanto stando ai tuoi consigli la Sp dovrebbe essere così:

CREATE PROCEDURE [dbo].[Sp_Searching] ( @search Varchar(50) ) AS BEGIN declare @categoria table (id int) declare @comune table (id int) declare @utente table (id int) insert into @categoria select id from tab_categorie where PATINDEX('%' + @search + '%', descrizione) >0 insert into @comune select id from tab_comuni where PATINDEX('%' + @search + '%', descrizione) >0 insert into @utente select id from tab_utenti where PATINDEX('%' + @search + '%', Utente) >0 insert into @utente select u.id from tab_utenti u inner join @comune c on u.idcomune=c.id insert into @utente select u.id from tab_utenti u inner join @categoria c on u.idcategoria=c.id select u.utente, c.descrizione as comune, ca.descrizione as categoria from tab_utenti u inner join tab_comuni c on c.id=u.Idcomune inner join tab_categorie ca on u.idcategoria=ca.id inner join @utente x on x.id=u.id END

puoi dirmi se va bene?

Senti una curiosità riguarda sempre google ma per aver preso esempio quello, mi hai detto che non usa database relazionati ed allora come fa, che tipo di database, e poi se hai un minuto mi spieghi un attimo il discorso dei dbcache?

ciao
Cirillo Fabio
www.wondernet.biz
fabio@wondernet.biz
http://blogs.dotnethell.it/fabiocirillo/
http://wnetsoftware.blogspot.com

trinity Profilo | Guru

Ciao Gluck...ho scritto e sperimentato la stored con i tuoi consigli....calcola che l'ho eseguita da sql management e mi connesso ad un server sql situato presso un provider americano (la crystaltech non so se la conosci)

ecco il codice:

ALTER PROCEDURE [dbo].[Sp_Searching] ( @search Varchar(50) ) AS BEGIN declare @categoria table (id int) declare @comune table (id int) declare @utente table (id int) insert into @categoria select id from tab_categorie where PATINDEX('%' + @search + '%', descrizione) >0 insert into @comune select id from tab_comuni where PATINDEX('%' + @search + '%', descrizione) >0 insert into @utente select id from tab_utenti where PATINDEX('%' + @search + '%', Utente) >0 insert into @utente select u.id from tab_utenti u inner join @comune c on u.idcomune=c.id insert into @utente select u.id from tab_utenti u inner join @categoria c on u.idcategoria=c.id select u.utente, c.descrizione as comune, ca.descrizione as categoria from tab_utenti u inner join tab_comuni c on c.id=u.Idcomune inner join tab_categorie ca on u.idcategoria=ca.id inner join @utente x on x.id=u.id END

nella tabella ci sono solo 2 record e il tempo di aver eseguito e visualizzato il risultato è stato questo: 00:00:00.5800008, non credi sia altino in confronto al test ed ai dati che mi avevi postato te?

ti posto anche le tabelle che ho scritto per vedere se c'è qualche errore lì....

Il codice sorgente non è stato renderizzato qui
perchè non c'è sufficiente spazio.
Clicca qui per visualizzarlo in una nuova finestra

invece se eseguo questa stored:

ALTER PROCEDURE [dbo].[Sp_Searching_test] ( @search Varchar(50) ) AS BEGIN select u.utente, c.descrizione as comune, ca.descrizione as categoria from tab_utenti u inner join tab_comuni c on c.id=u.idcomune inner join tab_categorie ca on u.idcategoria=ca.id where c.descrizione like '%' + @search + '%' or ca.descrizione like '%' + @search + '%' or u.utente like '%' + @search + '%' END

stessi record ecc... mi da questo risultato: 00:00:00.5380308

sai dirmi qualcosa?

ciao
Cirillo Fabio
www.wondernet.biz
fabio@wondernet.biz
http://blogs.dotnethell.it/fabiocirillo/
http://wnetsoftware.blogspot.com
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