Newsgroup: it.comp.lang.visual-basic
Titolo: query lenta

Ciao a tutti,
Uso DAO da VB6 per connettermi ad una tabella access con 240000 record.
Devo eseguire una query di questo genere:
SELECT TOP 1 CAMPO1 FROM TAB1 WHERE CAMPO1 LIKE 'xxx?xx'
dove xxx?xxx è una stringa che può variare e ? può trovarsi in diverse
posizioni nella stringa.
A me non interessa leggere il primo record trovato ma solo sapere se esiste
almeno un record che soddisfi la condizine (uso IF rs.EOF... per capirlo)
Il mio problema è che la query, soprattutto quando non trova alcun record, è
un po' lenta.
Esiste un modo per migliorare le prestazioni, magari usando ADO, la velocità
nel mio caso è fondamentale.
bye,
Max

 velocità nel mio caso è fondamentale.
No, ADO è leggermente meno performante, per cui non è lì che devi operare.
Credo che l'unica cosa che può darti dei risultati serii sia la creazione di 
un indice su CAMPO1.
Ciao
Alberto
-- 
E tutto mi sembrava andasse bene... 

Pensa anche se fosse possibile di ridisegnare la tua tabella. 
Ciao

 un indice su CAMPO1.
Non è vero...l'uso di LIKE esclude l'uso dell'indice; quindi non 
otterresti nessun miglioramento!

 nel mio caso è fondamentale.
Se fai uso frequente di questa ricerca, crea una stored procedure...la 
prima esecuzione sarà lenta, ma le altre saranno performanti.
Altra alternativa è migliorare il filtro, aggiungendo qualche altro 
filtro che escluda altri record.

 otterresti nessun miglioramento!
Non conosco Access al 100%, per cui mi fido.


 Non conosco Access al 100%, per cui mi fido.
Non è una questione di access o chi per esso...è una questione di database:
un indice su un campo non fa che creare un hash (impronta digitale 
univoca) che identifica un record (come un indice di un libro).
La clausola LIKE è utilizzata per cercare parti di testo, per cui,
è impossibile avere un hash preciso se non si conoscono a priori
il numero di car presenti e soprattutto la loro collocazione.
Es: ...campo LIKE '%a%' -- impossibile risalire ad un hash valido!!!
Ciao

 libro).
Beh, quando all'università studiavamo gli indici (e poi mi sono anche 
ritrovato il dimensionamento di un indice all'esame di stato) ce n'erano di 
tutti i tipi, anche a plain text, cioè con l'intero campo ridondante 
nell'indice.
Poi, Sql-Server non indicizza in plain-text, e sono d'accordo che col Like 
un indice non serva (esistono però delle funzioni di ricerca testuale molto 
più belle, ma è tutto un altro discorso).
Ma non ho idea di come indicizzi Access, per cui a priori non potevo sapere 
che usasse anche lui un algoritmo di elaborazione sul contenuto.


 nell'indice.
Puoi anche indicizzare tutto il campo, ma se nella clausola c'č '%a%'
non sarai mai in grado di utilizzare l'indice, perchč 'a' non basta
per identificare univocamente un record.
E anche vero che in alcuni casi il db č in grado di usare l'indice
con clausole LIKE...tipo 'chiavesufficiente%' (potrebbe utilizzarlo
perchč č in grado di creare un hash quasi preciso: di sicuro inzia con 
l'hash ottenuto perchč non c'č il carattere percentuale all'inizio). 
Ovviamente č solo un caso indicativo, di esempio.

 l'hash ottenuto perchè non c'è il carattere percentuale all'inizio).
Questo vale per un determinato tipo di algoritmo di hash, che abbia una 
qualche forma di sequenzialità concorde con il campo indicizzato.
Ma questo è una caso particolarissimo, nel senso che la teoria degli indici 
non richiede che ci sia un ordine di questo tipo.
Rimanendo sul generico, diciamo che avrebbero potuto esserci miglioramenti 
di performance notevoli, per ricerche a bassa hit-ratio su tabelle molto 
popolose o quantomeno con record molto onerosi, ma a condizione che una 
indicizzazione di quel tipo fosse supportata da Access, cosa che mi dici non 
essere vera.


 un po' lenta.
1) la tecnologia di accesso (ADO o DAO) non cambia assolutamente nulla in un 
caso come questo (quella incide se devi fare query piccole e molto 
numerose);
2) l'unica soluzione efficace č di cambiare la struttura del db in modo che 
si possa utilizzare un indice, magari anche avendo molti piů record piů 
piccoli (uno per ogni lettera del campo1, se la tua ricerca č sempre a una 
lettera, oppure uno per ogni parola se cerchi sempre parole). Oppure creare 
delle colonne calcolate che indicano sempre la presenza o meno di un 
determinato carattere (una per ogni lettera). Altra soluzione potrebbe 
essere utilizzare una indicizzazione full text, che perň non esiste in 
Access (in SQL Server sě). Oppure vedere se riesci ad usare un altro 
indicizzatore full-text tipo Microsoft Index Server, che perň possa 
indicizzare il contenuto di un DB relazionale (Fulcrum SearchServer lo fa, 
ma costa caro...).
Ciao
Elef 

Grazie a tutti per consigli e delucidazioni.
Sperimenterò.
bye,
Max

 SELECT TOP 1 CAMPO1 FROM TAB1 WHERE CAMPO1 LIKE 'xxx?xx'
Credo sia la TOP abbinata alla LIKE che ti rallenta tutto.
Almeno TOP puo toglierlo; e in questo caso, non essendo numeri è anche
pesantino.
Perchè infatti la query deve prima trovare tutti i record che LIKE 'xxx?xx'
e una volta fatto questo deve anche trovare quale è il più grande, per
giunta su stringhe invece che su numeri.
E sapere il TOP record a  te non interessa nulla.
Tu vuoi sapere se c'è o non c'è almeno un record.
Quindi togli il top.
Poi guarda bene se puoi semplificare la stringa che passi alla like.
Cosi come è fatta seve confrontare 3 caratteri, poi saltarne uno e poi
confrontarne altri 2.
Se potessi fare '*xxx*' sarebbe molto piu veloce
--
Greg

 Se potessi fare '*xxx*' sarebbe molto piu veloce
non vedo gli asterischi che pure ho scritto.
la stringa xxx racchiusa tra asterischi
l
--
Greg

 non vedo gli asterischi che pure ho scritto.
Però la vedi in grassetto, giusto?


 Alberto
Si giusto, la vedo in grasetto. Ho capito.
Vediamo se cosi ottengo il risultato che voglio:
'* xxx *'
* xxx *
"*xxx*"
Ma a parte questo, cosa ne pensi di tutto il mio ragionamento sulla query
lenta ? (top e like)
Ci ho messo del tempo per pensarci su e riflettere :)
--
Greg

 query lenta ? (top e like)
Non sono d'accordo.
Cioè, non credo proprio che il TOP possa comportare rallentamenti.
Considera che il TOP non significa 'il più grande', ma 'il primo che 
estrai'.
Se ci fosse un ORDER BY, e quindi il TOP assumesse il significato di 'più 
grande', sarei d'accordo. E' noto che l'ORDER BY, soprattutto su tabelle 
numerose e su query che ritornano molti record, è devastante come tempi di 
elaborazione, RAM e disco.
Ma senza ORDER BY, il TOP è al contrario un elemento di velocizzazione, in 
quanto porta il motore ad inviare al richiedente solo N record, anzichè 
tutti quelli estraibili (potenzialmente moltissimi). In Access il 
ragionamento è parzialmente danneggiato dal fatto che il TOP con ORDER BY 
può restituire ben più degli N record specificati dalla clausola stessa, ma 
il concetto rimane.
Ciao
