PDA

Visualizza la versione completa : [ACCESS] Velocità di ricerca tra LIKE e INSTR


servizio.e-mail
10-04-2011, 00:19
Salve a tutti!!

spero sia la sezione adeguata per il mio post

innanzitutto possiedo un DB ACCESS 2010 con:
- una tabella prodotti con tre campi:
CODICE;DESCRIZIONE;PREZZO;

- una maschera con una casella di testo libera e una combobox:
casella di testo non associata "CERCA"
combobox "RISULTATI" (i dati della combo provengono dalla query RICERCA)

- una query di selezione RICERCA

La query preleva il testo inserito da CERCA e valuta se il testo è contenuto all'interno del campo CODICE e restituisce i dati nella combobox RISULTATI (requery di RISULTATI nella maschera dopo l'aggiornamento di CERCA)

PROBLEMA:
- se effettuo la query con l'istruzione INSTR(codice;cerca) la tempistica di restituzione in RISULTATI si aggira sui 10-11 SECONDI :sonno: :sonno: :sonno:
- se effettuo la query con l'istruzione LIKE *[CERCA]* la tempistica di restituzione in RISULTATI si aggira sui 5-6 SECONDI :sonno:

premesso che non posso convertire in altro sistema il database a causa di problemi di sistema operativo, capacità di sviluppo (non conosco altri linguaggi) e licenze: E' POSSIBILE MIGLIORARE I TEMPI DI RICERCA utilizzando altre istruzioni (che però non sono riuscito a ritracciare)?

PS: tra un Celeron 1200 di 10 anni fa con 512 MB di ram e un Core 2 Duo a 1800 con 3 GB di ram la differenza di tempistica è di soli 2 - 3 secondi in più (macchine pulitissime)..... lo troverei strano ma...

Grazie a tutti in anticipo!!!

servizio.e-mail
10-04-2011, 00:28
scusatemi!!! ho dimenticato una cosa essenziale:
La tabella contiene circa 1 MILIONE DI RECORD su cui effettuare la ricerca

Grazie ancora!!

MItaly
10-04-2011, 00:30
(edit: ho detto una sciocchezza, Access non dispone di indici full-text)
(ri-edit: nel tuo caso non vanno neanche bene gli indici full-text)

Hai considerato la possibilità di passare il DB ad un motore di database più "serio"? Access (o meglio, Jet) non è fatto per fare lavori "pesanti"...

servizio.e-mail
10-04-2011, 01:46
un'esempio? premetto che è un caso assolutamente isolato e non remunerativo da parte di chi lo utilizza quindi non possiamo permetterci licenze costose (access era già presente e mi permette di usare il runtime gratuitamente) e cambio di sistema operativo verso linux. Ho provato a mettere su un sistema sql con la versione express di microsoft ma il punto è che se poi vado ad usare maschere in access torno ai tempi sopra menzionati (con un lavoro più complesso per l'installazione di sql)

se passassi tutto in visual studio sarebbe la soluzione definitiva oppure potrebbero esistere altre soluzioni?
ho fatto proprio ora una prova con una ricerca (sempre in ACCESS) e creazione di una tabella con i risultati con il seguente codice:

Dim Tabb1 As Recordset
Dim Tabb2 As Recordset
Set dbs = CurrentDb
Set Tabb1 = dbs.OpenRecordset("listino") 'tabella con i dati originali
Set Tabb2 = dbs.OpenRecordset("risultati") 'tabella con i risultati dei dati corrispondenti
Tabb1.OpenRecordset
Tabb2.OpenRecordset
MsgBox Forms!maschera1!cerca 'test da ricercare
Tabb1.MoveFirst
Do
' ricerca se il testo si trova all'interno del codice prodotto
If InStr(1, Tabb1!cod, Forms!maschera1!cerca, vbTextCompare) <> 0 Then
Tabb2.AddNew
Tabb2!cod = Tabb1!cod
Tabb2.Update
End If
Tabb1.MoveNext
Loop Until Tabb1.EOF
Tabb1.Close
Tabb2.Close

tempo totale circa 40 secondi!!! sarò ignorante ma non mi capacito di queste tempistiche...

la mia paura è di passare ad altro linguaggio, far fatica a istruirmi in merito e non ottenere nulla...

grazie!!!

MItaly
10-04-2011, 01:57
Aspé, ma tu stai facendo fare la ricerca al codice VBA? Per forza va lento! Usa una query SQL per effettuare la ricerca vera e propria, e VBA semplicemente per mettere i dati (già filtrati dal motore di DB) nella combobox.

Per inciso, Access può tranquillamente fare da frontend per un altro motore di DB.

servizio.e-mail
10-04-2011, 02:03
ops ne ho saltato un pezzo...
ho effettuato diverse prove:

prima prova:
query di access che usa instr
10-11 secondi di tempo di ricerca

seconda prova:
query di access che usa like
5-6 secondi di tempo di ricerca

terza prova:
ricerca in tabella con vba
40 secondi di tempo di ricerca

le prime due prove le ho effettuate sia con tabelle in access 2010 sia in sql server e non ho ottenuto variazioni significative sui tempi di ricerca...

contro che muro/soluzione vado a sbattere la testa?

grazie!

deleted_29
10-04-2011, 11:46
Ahemmm... provo un pochino a chiarire le cose, che in realtà son già chiare.

Non esiste un modo "magico" per il quale un RDBMS (comprendiamoci pure anche access) possa dare una risposta "veloce" ad una interrogazione che richiede una full-scan.

Cercare qualcosa con "like '%pippo%'" richiede la scansione di ogni singola riga della tabella, e la verifica all'interno di ogni stringa della presenza di una sotto-stringa.

Non ci sono "magie", che usi access, mysql, postgres, oracle o quello che vuoi quella è una query lenta.
---
Per renderla "veloce" ti occorrerebbe un motore specifico per questo tipo di ricerche, tipo ad esempio spinhx (ce ne sono altri, ti menziono questo perchè è quello ben integrato con mysql che uso normalmente).

In questo caso la ricerca che vuoi fare viene eseguita rapidamente (moooolto rapidamente, nell'ordine di millisecondi per un milione di righe).

Ma, se tralasciamo motori "furbi" che hanno indici "furbi", semplicemente, una LIKE %...% non può essere ottimizzata => sarà lenta comunque :mem:
---
Bene, QUANDO un RDBMS "normale" ti viene in aiuto? Quando in fase di ricerca hai un indice selettivo e lo puoi usare.

In questo caso una ricerca del tipo select * from tabella where (campo1='pippo') and (campo2='pluto') può essere notevolmente accelerata (in certi casi in realtà no, ma diciamo di sì)

Non ti suggerisco quindi di "spazzolare" un db riga per riga per verificare se nei campi c'è qualcosa (fullscan=>lento+overhead dell'applicazione=ancora più lenta), bensì di fare query che possono essere velocizzate dall'uso di indici.

Indici, per inciso, che servono solo nel caso di "=" o (nel caso migliore, per access non so) del tipo LIKE 'qualcosa%' ossia dove si prende la PRIMA parte della stringa

---
Infine, se proprio proprio vuoi mantenere questa metodologia, fossi in te ragionerei sulla possibilità di caricare in RAM (in un vettorone) l'intero DB, e poi fare le ricerche lì.
Non avresti miglioramenti giganteschi (sempre fullscan sono), ma di sicuro qualcosa migliori.
Una macchina moderna non fa fatica ad allocare fino a oltre 1GB di RAM per "vettoroni" di questo tipo.
:mem:

servizio.e-mail
10-04-2011, 12:39
Grazie infinite a tutti!!!!

speravo di essere carente in termini di linguaggio invece scopro che la comodita' di ricercare parte del codice deve per forza essere pagata con sistemi 'lenti' o con cambi sostanziali di sistema dati.

faro' sapere eventuali evoluzioni...

grazieeeeeeeeeeeeeeeeeeeeeee :ciauz: :ciauz: :ciauz:

Loading