Pagina 1 di 2 1 2 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 12
  1. #1

    Ottimizzazione funzione

    Ho un problemino più che altro teorico, che però potrebbe diventare importante nel caso di database molto grandi, con tanti records.

    Nel mio lavoro di sviluppatore questa situazione mi è già capitata diverse volte e, ritenendola di interesse generale, chiedo l'opinione di questo illustre forum.

    Sto dividendo una stringa (composta dai nomi e dai codici degli utenti collegati a un sito) per creare un array, e devo confrontare ogni elemento dell'array con un database (per contare, tra gli utenti collegati, quelli autenticati)

    Faccio:

    codice:
    Dim arrUtenti, i, utenti, aut
    
    arrUtenti = Split(Application("Utente"),"|")
     
    aut = 0
    
    set objaut=Server.createobject("ADODB.Connection") 
    objaut.ConnectionString = "DRIVER={Microsoft Access Driver (*.mdb)};DBQ=" &Server.mappath("/mdb-database/crm.mdb")
     
    objaut.open
    
    for i = 0 to UBound(arrUtenti)-1
    
    ' calcolo visitatori autenticati
    set rsaut = Server.CreateObject("ADODB.Recordset") 
    sql="SELECT * FROM login WHERE login ='"&(arrUtenti(i))&"'"
    
    rsaut.open sql, objaut, 3, 3
    
    if not rsaut.eof then
    	aut = aut + 1
    end if
    
    ... codice per presentare a video l'elenco degli utenti....
    
    rsaut.close
    set rsaut = nothing
    
    Next 
    
    ' visitatori totali in linea
    response.write ("Utenti connessi: "&i)
    response.write (" di cui autenticati: "&aut)
    
    objaut.Close 
    Set objaut = Nothing
    Come si vede, creo la connessione e, all'interno del ciclo che scorre gli elementi dell'array, per ogni elemento interrogo il database estraendo solo il record che corrisponde alla query, creo e apro un recordset, controllo se è vuoto, e poi lo chiudo e lo distruggo. Alla fine chiudo la connessione.

    In alternativa si può fare un'unica query che estrae tutti i records, creando un unico recordset, e poi per ogni elemento dell'array scorrere tutto il recordset estraendo i record corrispondenti. Alla fine chiudere e distruggere il recordset e la connessione una volta per tutte.

    Nel primo caso apro e chiudo il recordset tante volte quanti sono gli elementi dell'array, e poi devo limitarmi a controllare se è vuoto o no. L'elaborazione dei dati avviene a "livello del database", se così si può dire..

    Nel secondo apro e chiudo il recordset una sola volta, ma per ogni elemento dell'array devo scorrere tutto il recordset alla ricerca di eventuali records che soddisfano la condizione. L'elaborazione dei dati avviene "al di fuori del database".

    Qual' è il metodo migliore? O sono equivalenti?
    Come si può fare un test attendibile?

    Grazie a chiunque vorrà darmi un parere o un consiglio.......se non avrà niente di più serio di cui occuparsi.

    :maLOL:
    E' nato www.lombardiamotori.it

    www.universocase.it: il primo portale italiano di annunci immobiliari gratuiti e autogestiti!

  2. #2
    Moderatore di ASP e MS Server L'avatar di Roby_72
    Registrato dal
    Aug 2001
    Messaggi
    19,559
    Presumo la prima tecnica, quella che hai usato, sia la migliore.
    L'indicazione di una query con la WHERE credo sia più veloce di una generica da scorrere da capo a piedi.

    Roby


  3. #3
    Effettivamente questo metodo è direi il più ottimale anche se nel codice ho notato due pesanti errori che rallentano l'elaborazione, te li evidenzio:

    codice:
    Dim arrUtenti, i, utenti, aut
    
    arrUtenti = Split(Application("Utente"),"|")
     
    aut = 0
    
    set objaut=Server.createobject("ADODB.Connection") 
    objaut.ConnectionString = "DRIVER={Microsoft Access Driver (*.mdb)};DBQ=" &Server.mappath("/mdb-database/crm.mdb")
     
    objaut.open
    
    for i = 0 to UBound(arrUtenti)-1
    
    ' calcolo visitatori autenticati
    set rsaut = Server.CreateObject("ADODB.Recordset") 
    sql="SELECT * FROM login WHERE login ='"&(arrUtenti(i))&"'"
    
    rsaut.open sql, objaut, 3, 3
    
    if not rsaut.eof then
    	aut = aut + 1
    end if
    
    ... codice per presentare a video l'elenco degli utenti....
    
    rsaut.close
    set rsaut = nothing
    
    Next 
    
    ' visitatori totali in linea
    response.write ("Utenti connessi: "&i)
    response.write (" di cui autenticati: "&aut)
    
    objaut.Close 
    Set objaut = Nothing
    1.
    Usare una stringa con driver mdb è sicuramente meno performante che usare una stringa OLEDB

    2.
    Perchè creare e distruggere un recordset ad ogni passaggio?
    E' un dispendio di risorse in elaborazione enorme ed inutile poichè parli di un ciclo.

    Sposta la creazione e la distruzione fuori dal ciclo.
    Crea il recordset, entra nel ciclo eseguendo le query che ti servono ed a fine ciclo distruggi l'oggetto.

    Eviterai di crearlo/distriggerlo ad ogni ciclo, cosa che comporta ovviamente un numero di risorse necessarie maggiore.

    Ci sarebbe ancora una 3 cosa che aiuterebbe ad alleggerire il carico ma è un po' complessa... vedo di riordinare le idee su come segnalarla e poi la posto.

  4. #4
    ...grazie... i soliti leoni sempre in trincea, anche di domenica, eh?

    Usare una stringa con driver mdb è sicuramente meno performante che usare una stringa OLEDB
    Non lo sapevo, ok!
    Perchè creare e distruggere un recordset ad ogni passaggio?
    Basta aprire e chiudere, non serve creare e distruggere ogni volta?

    Però.......io non devo riaprire ad ogni ciclo lo stesso recordset, me ne serve un altro.........

    :master:
    E' nato www.lombardiamotori.it

    www.universocase.it: il primo portale italiano di annunci immobiliari gratuiti e autogestiti!

  5. #5
    Moderatore di ASP e MS Server L'avatar di Roby_72
    Registrato dal
    Aug 2001
    Messaggi
    19,559
    E' un altro recordset ma lo chiami allo stesso modo quindi prova a fare così:

    codice:
    set rsaut = Server.CreateObject("ADODB.Recordset") 
    for i = 0 to UBound(arrUtenti)-1
    
    sql="...."
    rsaut.open sql, objaut, 3, 3
    ...
    rsaut.close
    
    Next 
    set rsaut = nothing
    Roby

  6. #6
    Basta aprire e chiudere, non serve creare e distruggere ogni volta?
    Esatto.
    Roby ti ha già segnalato come.

  7. #7
    Sì, avete ragione, va benissimo lo stesso.

    E' nato www.lombardiamotori.it

    www.universocase.it: il primo portale italiano di annunci immobiliari gratuiti e autogestiti!

  8. #8
    usa la clausola ...WHERE campo IN elenco..., invece di fare tutti quei giri... in un colpo solo (usando la COUNT(), OC!) sai *quanti* sono gli utenti collegati in quel momento.

  9. #9
    Quindi, fuori dal primo ciclo:

    codice:
    sql="SELECT COUNT(*) FROM login WHERE login IN '"&arrUtenti&"'"
    Se va, non è mica male......... :master:
    E' nato www.lombardiamotori.it

    www.universocase.it: il primo portale italiano di annunci immobiliari gratuiti e autogestiti!

  10. #10
    Utente di HTML.it L'avatar di kluster
    Registrato dal
    Jul 2003
    Messaggi
    1,288
    te la devi costruire lavorando su arrUtenti (vedo che non leggi i private)

    codice:
    arrUtenti = Split(Application("Utente"),"|")
     
    
    TotaleUser = Ubound(ArrUtenti) 
    StrUtenti = "'" & Join(ArrUtenti,"','") & "'" 
    Response.Write "PER DEBUG: 
    <h1>" & StrUtenti & "</h1><hr>" 
    SQL = "SELECT id,user FROM T_LOGIN WHERE Login In (" & StrUtenti & ");" 
    Set Rs = Server.CreateObject("Adodb.Recordset") 
    Rs.Open SQL,Connection,3,3 
    Response.Write "Totale Utenti : " & TotaleUser & "
    " 
    Response.Write "Totale Utenti Loggati : " & Rs.RecordCount & "
    " 
    Response.Write "Totale Utenti non Loggati : " & TotaleUser - Rs.RecordCount & "
    
    "

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2026 vBulletin Solutions, Inc. All rights reserved.