Newsgroup: it.comp.appl.access
Titolo: [ot] Execution plan per giorgio rancati

Chiedo scusa per questo messaggio ot, poiche' riguarda sql server, ma non
riesco a trovare risposte piu' convincenti di quelle che il gentile giorgio
rancati mi ha dato su questo ng. Ho iniziato a postare qui passando da
Access a Sql Server, e ne sto conoscendo le potenzialita'.
In particolare per una vecchia query postata qui ho analizzato, come da
consiglio di giorgio, l'execution plan, e ho visto che a seconda dei casi
Sql Server usa per l'INNER JOIN la tecnica "Hash Match/Inner Join", mentre
per i LEFT JOIN "Nested Loops/Left Outer Join" o a volte "Hash Match/Right
Outer Join".
Nel caso di "Nested Loops/Left Outer Join" a volte usa una "Table Spool/Lazy
Spool" per velocizzare l'esecuzione, a volte no.
Quello che mi chiedo e' se e' possibile influenzare tale piano di
esecuzione????
Ad es. aggiungendo un indice a volte ho influenzato il piano, ma nello
specifico mi serve far utilizzare la "Table Spool/Lazy Spool" a un LEFT
JOIN.
Infatti se eseguo questa query...
SELECT TOP 100 TPrv.id AS id, ord2 AS ordpref2, ord3 AS ordpref3, ord4 AS
ordpref4,
ord5 AS ordpref5, ord6 AS ordpref6, ord7 AS ordpref7
INTO temp_1 FROM data AS TPrv INNER JOIN
[prcampo2] AS TPrf2 ON TPrf2.valorecampo2 = TPrv.campo2 INNER JOIN
[prcampo3] AS TPrf3 ON TPrf3.valorecampo3 = TPrv.campo3 INNER JOIN
[prcampo4] AS TPrf4 ON TPrf4.valorecampo4 = TPrv.campo4 INNER 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
...gli ultimi due LEFT JOIN vengono eseguiti con la tecnica "Nested
Loops/Left Outer Join" utilizzando una "Table Spool/Lazy Spool", mentre
nella query seguente...
SELECT TOP 100 TPrv.id AS id, ord2 AS ordpref2, ord3 AS ordpref3, ord4 AS
ordpref4,
ord5 AS ordpref5, ord6 AS ordpref6, ord7 AS ordpref7
INTO temp_1 FROM data AS TPrv INNER JOIN
[prcampo2] AS TPrf2 ON TPrf2.valorecampo2 = TPrv.campo2 INNER JOIN
[prcampo3] AS TPrf3 ON TPrf3.valorecampo3 = TPrv.campo3 INNER JOIN
[prcampo4] AS TPrf4 ON TPrf4.valorecampo4 = TPrv.campo4 INNER JOIN
[prcampo5] AS TPrf5 ON TPrf5.valorecampo5 = TPrv.campo5 INNER JOIN
[prcampo6] AS TPrf6 ON TPrf6.valorecampo6 = TPrv.campo6 LEFT JOIN
[prcampo7] AS TPrf7 ON TPrf7.valorecampo7 = TPrv.campo7
...il "Nested Loops/Left Outer Join" NON utilizzando la "Table Spool/Lazy
Spool", e ci impiega solo per quest'ultimo JOIN 1 minuto e mezzo contro i 4
secondi della query precedente!
Come posso fare?
GRAZIE!


[CUT]
Ciao,
puoi modificare il metodo di Join e l'ordine dei join ma non credo che si
possa modificare il modo di leggere una tabella.
es
--------------------
SELECT A.Codice
FROM   A
  LEFT HASH JOIN B
    ON A.Codice=B.Codice
  LEFT MERGE JOIN C
    ON A.Codice=C.Codcie
OPTION (FORCE ORDER)
------------------
come vedi la prima left join utilizza il metodo Hash mentre la seconda il
metodo Merge, l'option in fondo forza l'ordine dei join cosě come sono
scritti. Ma in genere č meglio lasciar fare a Sql Server.
Il resto degli HINT li trovi nel manuale in linea a questo indirizzo
-------------
URL:acdata.chm::/ac_8_qd_03_8upf.htm
-------------
ma non c'č quello che cerchi :(
Ciao Giorgio

 scritti. Ma in genere č meglio lasciar fare a Sql Server.
Nella mia seconda query non riesco pero' proprio a capire come mai SqlServer
scelga una strategia che si rivela inefficace (impiega 1 min e mezzo, contro
i 4 secondi della prima!)?!?
Solitamente gli Inner Join vengono eseguiti come Hash, e se forzo solo
l'ultimo Join (LEFT HASH JOIN) SqlServer esegue i precedenti (gli Inner)
come Merge, e non piů come Hash. Per ottenere il tempo minore devo forzare
tutti i Join come Hash (INNER HASH JOIN e LEFT HASH JOIN)... come mai
SqlServer non fa questa scelta da solo???
Sempre GRAZIE!

 scritti. Ma in genere č meglio lasciar fare a Sql Server.
Nella mia seconda query non riesco pero' proprio a capire come mai SqlServer


"@@@" <viaseg...@SPAMdespammed.com> ha scritto nel messaggio
news:1%CBc.9833$c_1.3...@twister1.libero.it...

domanta da 1.000.000 di euri :-)
Quello che so č che Sql Server sceglie il piano di esecuzione in base alle
statistiche delle varie tabelle e indici in gioco.
Prova a rigenerare tutti gli indici di tutte le tabelle del tuo Db con
--------------------------
DBCC DBREINDEXALL ('TuoDb')
--------------------------
poi č meglio compattare il database
-----------------
DBCC SHRINKDATABASE('TuoDb')
-----------------
prova a generare le statistiche di tutte le tabelle con ...
---------------------------
USE TuoDb
GO
EXEC sp_updatestats
GO
---------------------------
Controlla che il db in questione abbia l'opzione *auto update statistics*
impostata a ON con.....
-------------------------
EXEC sp_dboption 'TuoDb','auto update statistics'
------------------------
e nel caso sia a OFF .....
------------------------
EXEC sp_dboption 'TuoDb','auto update statistics','On'
------------------------
Ciao Giorgio

 statistiche delle varie tabelle e indici in gioco.
Ho fatto tutte le tue operazioni, e il JOIN in questione non fa piu' il
LOOP, ma l'HASH, impiegando pochi secondi.
Una tua interpretazione per favore, e non ti rompo piu'...: a cosa era
dovuto secondo te il problema, e perche', o meglio come, l'ho risolto?
Infine una domanda forse stupida (della quale eventualmente mi scuso):
perche' il LEFT JOIN compare come Hash Match/Right Outer Join? perche'
Right?
GRAZIE!
...spero un giorno di poter ricambiare...

> Prova a rigenerare tutti gli indici di tutte le tabelle del tuo Db con
Non e' possibile quando DATA ha 240000 rows, e il primo "campo2" 12 rows,
avevo impiegato 13 secondi a fare la query... ora ce ne mette solo 4!!!
Cos'ho fatto, o cosa mi hai fatto fare, per migliorare cosi' le prestazioni?

...spero un giorno di poter ricambiare...
per me è già una grande soddisfazione essere riuscito a darti una mano dove
i grandi non hanno risposto. :-)
Ciao Giorgio

"@@@" <viaseg...@SPAMdespammed.com> ha scritto nel messaggio
news:QnHBc.10473$c_1.3...@twister1.libero.it...

Ma i miglioramenti menzionati nel post precedente li hai avuti senza la
rigenerazione degli indici ?
Ciao Giorgio

 rigenerazione degli indici ?
No no, i miglioramenti di cui parlo dopo aver fatto tutto quello che mi hai
elencato... il problema e' che sono meravigliato dal fatto che rigenerare
gli indici cambi praticamente tutto: il piano di esecuzione e' diverso, i
tempi anche... sinceramente sono un po' perplesso da questo, nonostante le
tue spiegazioni!
Comunque sei stato gentile e utilissimo a capire delle cose, non so di che
"grandi" parli, ma a me non ha risposto nessuno eccetto te, e di questo
ovviamente ti ringrazio!
Vado un po' a documentarmi, e domani proseguo con altri test...
eventualmente ti faccio sapere!
Grazie,
David.

 tue spiegazioni!
Evidentemente il database era in uno stato pessimo con indici molto
frammentati (causa molti inserimenti e cancellazioni) il cui utilizzo
avrebbe compromesso ulteriormente le prestazioni.
Ciao Giorgio