Newsgroup: it.comp.lang.visual-basic
Titolo: [?][OT]Query MySql (reprise)

 AND A.DATA=B.DATA
Come promesso, non appena l'ho provata ho postato.
La query, per funzionare, funziona. Purtroppo su una tabella
da 13000 record, per estrapolarne 1800, impiega tra i 15 e i
20 secondi... un tempo assolutamente inadeguato, per il tipo
di applicazione che sto sviluppando.
Il DB e' MySQL, il collegamento lo effettuo con
VBMySQLDirect 1.02, un componente che dialoga direttamente
col motore di MySQL (niente odbc). VBMySQLDirect e' dalle 3
alle 8 volte piu' veloce di ADO, a seconda dell'operazione
che si vuole svolgere, ma supporta solo connessioni lato
client, tutti i recordset sono statici e "updatable".
Il DB e' composto di 60 tabelle, la piu' grande e' quella
che sto interrogando, 13000 record per un totale di 1,7MB.
Tutto il DB contiene 120000 record, per un totale di 7,6MB.
Avete qualche suggerimento su come velocizzare la query?
Sono disposto anche a cambiare la struttura della/e
tabella/e.
Per completezza posto la mia query:
TableName = "`anagraficaarticoli_200502`"
Query = _
"SELECT *" & _
" FROM " & TableName & " AS `A`" & _
" INNER JOIN" & _
" (SELECT " & _
" `id`, `nome`, `categoria`, `sottocategoria`," & _
" `idfornitore`, `um`, `idtipoiva`, `prezzoacquisto`," & _
" `tipoprezzo`, `riferimentoprezzo`, `prezzononvalido`," & _
" `tempoconsegna`, `descrizionetempoconsegna`," & _
" `iddistributorepredefinito`, `marginalitaprezzo`," & _
" `prezzofisso`, `stocca`, `pezzipercartone`," & _
" `umordineminimo`, `ordineminimo`," & _
" MAX(udata) AS udata" & _
" FROM " & TableName & _
" WHERE `udata` <= '" & UData & "'" & _
" GROUP BY id" & _
" ) AS `B`" & _
" ON `A`.`id`=`B`.`id`" & _
" AND `A`.`udata`=`B`.`udata`;"
Grazie per l'aiuto,
Lokar

 " AND `A`.`udata`=`B`.`udata`;"
Parallelamente, lavorerei sugli indici.
I tempi che riporti sono assolutamente intollerabili.
Query del tutto simili, su tabelle da alcuni milioni di record, 
terminano in Sql-Server su un server 'base' in tempi nell'ordine di 2-3 
secondi (alla seconda esecuzione, of course, alla prima magari anche 
5-6 secondi).
Deduco quindi, visto che MySql è almeno altrettanto veloce, che manchi 
una gestione degli indici.
Per il tuo caso, credo che un indice Clustered su UDATA DESC, ID ti 
possa ridurre i tempi anche di un ordine di grandezza.
Se gli inserimenti sono sempre per data maggiore della precedente, 
potresti anche usare un Fill Factor vicino a 100%, e avresti veramente 
il top.
Se invece a volte inserisci record con date 'passate', prevedi un Fill 
Factor di 80-85%, e un REINDEX periodico, ad esempio una volta alla 
settimana, di notte o di domenica.
Ciao
Alberto
-- 
Si è visto di meglio,
ma si è scopato di peggio,
qualche volta a pago
e non erano neanche sempre donne
[Paolo]

 domenica.
Mhhh.
"Indice Clustered"?
"DESC" = descrizione articolo?
"Fill Factor"?
"Reindex"?
Non ho idea di dove mettere le mani...  8,)
Vado ad istruirmi, va!
Comunque ho fatto una prova al volo, modoficando la query
ed "aggiungendo" gli indici... tempo di esecuzione:
~1 secondo.
/me sbatte violentemente la testa sulla parete.
Grazie di cuore,
Lokar

 ~1 secondo.
Con indici 'a caso', immagino...
Ma in genere un indice generato con 'avanti avanti avanti' è clustered, 
per cui eri sulla buona strada.


 prima :P
Non credo tu abbia colto a fondo la gravità della cosa che facevi.
Estraendo sia A.* che B.*, tu estraevi due volte, ad esempio, la 
colonna 'prezzofisso'.
Quindi, all'interno del recordset, ottenevi due colonne con lo stesso 
nome.
Facendo:
Label1.Caption=RCs.Fields.Item("PrezzoFisso").Value
quale delle due colonne visualizzi?
A.PrezzoFisso O B.PrezzoFisso?
Non lo sai.
Ma, diresti tu, non importa, tanto sono la stessa cosa.
Ma, dico io, manco po'o cazzo...
A.PrezzoFisso è il valore contenuto nel record identificato da quell'ID 
e da quella UData ottenuta col Max, ed è quindi effettivamente quello 
che ti serve.
B.PrezzoFisso è il valore contenuto in un *qualunque* record fra quelli 
rientranti nel [Group By ID] della SubQuery. Potrebbe quindi non 
centrare una fava col record che hai correttamente individuato.
Al di là, quindi, della ovvia perdita di performance dovuta 
all'overhead di traffico di rete e/o attraverso il Provider, stavi 
facendo una cosa che spostava la tua query da un qualcosa di 
deterministico a un qualcosa di indeterminato.


 indeterminato.
Confermo che con quella query, mi si incasinavano "anche" i
record =)
Grazie ancora,
Lokar
P.S. Appena trovero' un modo di implementare (Indice Clustered,
Fill Factor, Reindex) le tecniche da te descritte su
MySQL mi faro' vedere in un altro post. 

 secondo peggio :P
Tranqui.
Sono fatto così, parlo come magno, e magno come uno scaricatore di 
porto.
Ma non sono cattivo.
