Newsgroup: it.comp.appl.access
Titolo: Perche' questi tempi di esecuzione con i JOIN?

Ciao a tutti,
vorrei cortesemente che qualcuno di voi mi aiutasse a capire come mai una
query impiega piu' tempo ad essere eseguita piuttosto che una sua gemella
minore.
Ho la query seguente, dove pero' ordinepref5, ordinepref6, ordinepref7 sono
tutte tabelle vuote, per cui nei JOIN genera tutti valori pari a 100:
SELECT TOP 100 TPrv.id AS id,
ISNULL(TPrf2.ordinepref2,100) AS ordpref2,
ISNULL(TPrf3.ordinepref3,100) AS ordpref3,
ISNULL(TPrf4.ordinepref4,100) AS ordpref4,
ISNULL(TPrf5.ordinepref5,100) AS ordpref5,
ISNULL(TPrf6.ordinepref6,100) AS ordpref6,
ISNULL(TPrf7.ordinepref7,100) AS ordpref7
INTO temp_1 FROM (((((data AS TPrv INNER JOIN
[prcampo2] AS TPrf2 ON TPrf2.valorecampo2 = TPrv.campo2) LEFT JOIN
[prcampo3] AS TPrf3 ON TPrf3.valorecampo3 = TPrv.campo3) LEFT JOIN
[prcampo4] AS TPrf4 ON TPrf4.valorecampo4 = TPrv.campo4) LEFT JOIN
[prcampo5] AS TPrf5 ON TPrf5.valorecampo5 = TPrv.campo5) LEFT JOIN
[prcampo6] AS TPrf6 ON TPrf6.valorecampo6 = TPrv.campo6) LEFT JOIN
[prcampo7] AS TPrf7 ON TPrf7.valorecampo7 = TPrv.campo7
ORDER BY ordpref2, ordpref3, ordpref4, ordpref5, ordpref6, ordpref7;
La modifico in questo modo:
SELECT TOP 100 TPrv.id AS id,
ISNULL(TPrf2.ordinepref2,100) AS ordpref2,
ISNULL(TPrf3.ordinepref3,100) AS ordpref3,
ISNULL(TPrf4.ordinepref4,100) AS ordpref4
INTO temp_1 FROM ((data AS TPrv INNER JOIN
[prcampo2] AS TPrf2 ON TPrf2.valorecampo2 = TPrv.campo2) LEFT JOIN
[prcampo3] AS TPrf3 ON TPrf3.valorecampo3 = TPrv.campo3) LEFT JOIN
[prcampo4] AS TPrf4 ON TPrf4.valorecampo4 = TPrv.campo4
ORDER BY ordpref2, ordpref3, ordpref4;
Pero' la prima impiega circa 600 ms ad essere eseguita, la seconda sempre e
solo circa 900 ms... non dovrebbe invece impiegare meno tempo considerato
che ci sono 3 JOIN in meno seppur nulli?!?
Grazie.

 ha scritto nel messaggio
news:3D%yc.55564$Wc.17...@twister2.libero.it...

Hai verificato il numero di RecordsAffected nel 1° e nel 2° caso....???
Se il numero di Records inclusi è minore avendo inserito un maggior numero
di Join è ovvio che sia più veloce....!!!
Ciao.
@Alex.


Ciao,
prima di dire che una query è più veloce dell'altra dovresti azzerare il
buffer di Sqlserver
------------
DBCC FREEPROCCACHE
DBCC DROPCLEANBUFFERS
-------------
poi analizzare il piano di esecuzione per vedere come viene interpretata,
se vengono usati gli indici a disposizione e in che modo, Index Seek o Index
Scan. La seconda query potrebbe diventare più veloce della prima con
l'aumentare delle righe nelle varie tabelle.
Ciao Giorgio

 di Join è ovvio che sia più veloce....!!!
Sono LEFT JOIN per cui le righe sono le stesse, solo che nel primo caso ho 3
colonne in piu' che hanno pero' tutti valori 100, al posto di <NULL>.
I record sono sempre 100 in totale (TOP 100), e sono gli stessi!

 l'aumentare delle righe nelle varie tabelle.
Come rispondevo ad Alessandro ho sempre 100 righe, le stesse per altro, solo
che nella prima ho 3 colonne in piu' con tutti valori 100, al posto del
NULL... (ovviamente ricordi la questione del NULL!!!).


be, le tabelle sottostanti avranno più di 100 righe altrimenti che
significato ha Top 100 ?
Le 100 righe sono il risultato che può derivare da 10.000 righe.
Ciao Giorgio

> Le 100 righe sono il risultato che può derivare da 10.000 righe.
Si sono d'accordo ma la tabella DATA e' la stessa per tutte e due le query,
e cosi' le prime 3 tabelle con cui fa i JOIN... sono le stesse! L'unica
aggiunta sono 3 tabelle vuote, e francamente non capisco come facciano ad
allegerire il carico di lavoro...
Ho svuotato i buffer, ci sono sempre quei 200/300 ms di differenza, che,
considerati i tempi piuttosto simili se sottopongo l'algoritmo a diversi
carichi, sono tanti!!!
Mi interessava capire se puo' esserci un motivo a questo scostamento, se
devo dare dei risultati sperimentali non riesco davvero a capire come mai:
1) la stessa DATA fa il JOIN con 3 tabelle ed impiega 1000/900 ms;
2) la stessa DATA fa il JOIN con 4 tabelle ed impiega 530 ms;
3) la stessa DATA fa il JOIN con 5 tabelle ed impiega 640 ms;
4) la stessa DATA fa il JOIN con 6 tabelle ed impiega 760 ms.
Dalla 2 alla 4 com'e' naturale i tempi salgono, ma perche' al punto 1 (la
query corrisponde alla seconda che vi ho postato) impiega cosi' tanto? per
di piu' impiega di piu' che se faccio il JOIN con 6 tabelle, di cui 3 vuote?
Se con queste info ho generato confusione provo a spiegarmi di nuovo.
Grazie.

 4) la stessa DATA fa il JOIN con 6 tabelle ed impiega 760 ms.
Chiedo scusa non ho specificato che in questi casi le prime 3 tabelle con
cui DATA fa il JOIN sono sempre le stesse. I JOIN successivi non
diminuiscono il numero delle tuple (100) perche' sono LEFT JOIN.
Grazie.

 ha scritto nel messaggio
news:dZ0zc.107754$Qc.41...@twister1.libero.it...

Ciao,
non avevo fatto caso alle parentesi nelle Join, prova a toglierle tutte, in
questo modo lasci libero l'Optimizer di determinare la migior esecuzione. Se
stai provando le Query da Query Analyzer in connessioni diverse è già
capitato che la seconda connessione sia più lenta della prima, prova a
chiuderlo (Query Analyzer) e riaprirlo, poi esegui prima la seconda Query
(la più lenta) e poi la prima (quella più veloce).
Ciao Giorgio

 questo modo lasci libero l'Optimizer di determinare la migior esecuzione.
Rimane ahime' 891 ms, contro 501 ms. I tempi sono calcolati con un algoritmo
Java, e anche se la prima esecuzione torvasse memeoria libera, io ripeto
piu' volte il lancio della query.
Le parentesi le avevo messe semplicemente per dare priorita' all'INNER JOIN
che elimina subito diverse migliaia di tuple... l'Optimizer credi lo faccia
da solo questo ragionamento?
Comunque ecco i risultati (le prime 3 tabelle che fanno il JOIN con DATA
sono sempre le stesse):
1) DATA JOIN 3 tabelle : 871
2) DATA JOIN 4 tabelle : 1192
3) DATA JOIN 5 tabelle : 530 (perche' se le prime 4 tabelle sono le stesse
del JOIN precedente???)
4) DATA JOIN 6 tabelle : 641
5) DATA JOIN 6 tabelle (di cui le solite prime 3, e le ultime 3 vuote) : 511
Impossibili da interpretare questi dati!!!
Forse e' determinante che le tabelle sono delle viste? Sono comunque
semplicemente delle SELECT * FROM prf WHERE id=?
Se non sbaglio una vista di questo tipo deve comunque scorrere tutta la
tebella "prf" per selezionare le tuple, e questa tabella e' la stessa per
ogni vista!
Non so piu' cosa pensare...!

> poi analizzare il piano di esecuzione per vedere come viene interpretata,
Aiutami per favore a capire questi dati:
-- Trace Query (1)
SELECT... Duration: 9 - CPU: 205 - Reads: 104
-- Trace Query (2)
SELECT... Duration: 124 - CPU: 44 - Reads: 68
-- Estimated Execution Plan Query (1)
C'e' l'iniziale "Table scan" (DATA) e in cascata 6 "Table scan" e 1 "Hash
Match/Inner..." e 5 "Hash Match/Right...".
Tutti hanno COST 0%, tranne il penultimo "Hash Match/Right..." con 1% e
l'ultimo "Hash Match/Right..." con 2%.
"Sort/TopN" ha COST 97%.
-- Estimated Execution Plan Query (2)
C'e' l'iniziale "Table scan" (DATA) e in cascata 3 "Table scan" e 1 "Hash
Match/Inner..." e 2 "Hash Match/Right...".
Ad eccezione del primo "Table scan" 0%, tutti gli altri "Table scan" hanno
COST 3%, mentre tutti gli "Hash Match/*..." hanno COST 0%.
"Sort/TopN" ha COST 96%.
Ricordo che i dati contenuti in DATA, PRCAMPO2, PRCAMPO3, PRCAMPO4 delle due
query sono gli stessi, mentre per la prima PRCAMPO5, PRCAMPO6, PRCAMPO7 sono
tabelle vuote!!!
GRAZIE.


Se id è un indice non viene passata tutta la tabella
Ciao Giorgio