Newsgroup: it.comp.software.database
Titolo: MS SQL Server: lentezza di una view

Ciao a tutti,
mi e' capitato il seguente problema: ho un database di sviluppo su una
macchina Windows XP con SQL Server 2000 Developer Edition, all'interno di
questo database ho creato una view che lega tra di loro 15 tabelle, ma
alcune in modo ripetuto con alias diversi (per cui i legami sono 23), 3 in
inner join e le restanti in left join.
Questa view sul mio database di prova, sia su un Athlon XP 2Ghz con 768 MB
di RAM sia su un portatile Celeron 800 Mhz con 512 MB (sempre con Windows
XP e la stessa versione di SQL Server con le ultime sp) facendo una banale
"select * from " mi restituisce i record (circa 10, il database e' ancora
vuoto) in circa 1 o 2 secondi.
Vado dal cliente, installo tutto , faccio i primi test e vedo che la stessa
view, facendo la stessa operazione, mi restituisce i record (in questo caso
6) in 30/35 secondi, testato con il Query Analizer.
A volte ripetendo la query i tempi calano a pochi secondi ma basta mettere
una condizione diversa e il problema si ripropone.
Le tabelle collegate tra loro non hanno più di una ventina di record
ciascuna.
La cosa che mi sorprende e' che tali ritardi li ho su due macchine del
cliente diverse, con 4 CPU e 1.5 GB di RAM e Windows 2000 Server, senza
particolari carichi di lavoro (controllato da task manager).
L'unica differenza che devo verificare e' una possibile diversa collation
fra i miei server e quelli del cliente, ma in ogni caso i database li ho
creati da script, non da restore o attach dei device e una tale discrepanza
di performance considerato anche le potenze in gioco non le capisco.
Avete qualche suggerimento ?
Ciao
Starsky

 Avete qualche suggerimento ?
Semplificare la query :-)
23 JOIN (di cui 20 OUTER JOIN) non sono proprio leggere...
- Hai provato a scomporre la query in n viste, UDF o stored procedures?
- Hai considerato una denormalizzazione oculata del db?
- Ti sei ricordato di indicizzare le FK?
- Gli indici che hai creato sono utili all'esecuzione della query?
- I data type utilizzati per le PK e le FK sono "sufficientemente piccoli"
(come dimensioni in bytes)?
- Hai verificato lo stato di frammentazione delle data pages e delle index
pages?
-- 
Lorenzo Benaglia
Microsoft MVP - SQL Server
http://mvp.support.microsoft.com
http://italy.mvps.org

 
bhe... fare una query su un database di prova che ci impiega 1 o 2 
secondi, qualche dubbio sulla complessità me lo sarei fatto venire...
M.

 secondi, qualche dubbio sulla complessità me lo sarei fatto venire...
:-)
Siamo in 2


> secondi, qualche dubbio sulla complessità me lo sarei fatto venire...
:-)
Assolutamente d'accordo sul fatto che la query non sia il massimo,
purtroppo mi sono ritrovato a dover accelerare il rilascio di prova e la
soluzione piu' rapida che avevo trovato e' fare questa view da usare come
base per altri compiti.
Premesso questo pero' non capisco tutt'ora una tale differenza di
prestazioni, considerando le macchine provate.
Controllero' i punti elencati che mi hai segnalato ma in ogni caso
provvederò a semplificare le query...
Aggiungo un'altra domanda: qual'e' il numero massimo di tabelle da unire in
join (inner o left) che e' considerato "normale" e che sicuramente non da
problemi ? 
Ciao
Starsky

 sicuramente non da problemi ?
Ciao Starsky,
non esiste una formula magica che ti restituisce tale numero, le variabili
in gioco sono troppe e cambiano da progetto a progetto.
Solo tu puoi rispondere a questa domanda, identificando n strade alternative
che ti forniscono il medesimo result set e scegliendo quella più efficiente.
Ciao!


 - Ti sei ricordato di indicizzare le FK?
scusa l'ignoranza, se le righe fattura hanno il cod.prodotto
quest'ultimo è l'FK giusto?
E se si,  consigli di metterci un indice?
ciao

 ciao
Ciao!


 l'operatore di JOIN è opportuno ricordarsi di definire un indice.
nella testa ho questa sequenza e.g.:
- accesso al recordset di dettaglio fatture
- per ogni riga decodifica del prodotto sulla tabella apposita
in questo caso non vedo l'utilizzo dell'indice sulla FK, immagino quindi
che la JOIN sia diversa da un programma cobol! ;)
Hai due secondi per spiegarmi meglio? Ciao

 Hai due secondi per spiegarmi meglio? Ciao
Non è la JOIN "ad essere diversa da un programma cobol" ma lo è il modo di 
lavorare di un database server. Per soddisfare un join l'ottimizzatore di 
query di SQL Server può utilizzare diverse tecniche a seconda delle 
casistiche (quantità di record, presenza di indici, ecc) una delle quali 
(denominata nested loop join) è simile, nel modus operandi, a quanto da te 
indicato. Ed è anche la meno efficiente...
Entrare nel dettaglio degli algoritmi di join richiede un po più di 2 
secondi (molto di più) ma ti invito, se vuoi, ad approfondire l'argomento 
sul Book On Line di SQL Server cercando le voci "Nested loop join", "Merge 
join" e "Hash join".
Bye
-- 
Luca Bianchi


 Hai due secondi per spiegarmi meglio? Ciao
Ciao Paolo,
Cobol, che meraviglia, lo sai che iniziai ad occuparmi di informatica
lavorando proprio in ambienti Host sviluppando transazioni Cobol/CICS con
VSAM/DB2? :-)
Utilizzando il tuo approccio, l'indice definito sulla FK non serve ad un bel
niente... ma a questo punto mi chiedo che vantaggi hai ad utilizzare un DBMS
rispetto ad un file VSAM :-)
Per avere la denominazione del prodotto, potresti scrivere una semplice
query che ti restituisce "di botto" le righe fattura con il relativo
prodotto.
Esempio:
       +--------------+       +--------------+
       | RigheFatture |       | Prodotti     |
       +--------------+    1  +--------------+
PK     | FatturaID    |   +---| ProdottoID   | PK
PK, FK | ProdottoID   |<--+   | Nome         |
       | Colonna1     | Molti | FornitoreID  |
       | ...          |       | ...          |
       | ColonnaN     |       +--------------+
       +--------------+
Query:
SELECT RF.FatturaID
    , RF.Colonna1
    , ...
    , RF.ColonnaN
    , P.Nome
FROM Prodotti AS P INNER JOIN RigheFatture AS RF
ON P.ProdottoID = RF.ProdottoID
In questo modo eviti di dover fare un ulteriore lookup sulla tabella
Prodotti per recuperare il nome.


 rispetto ad un file VSAM :-)
ah ecco! ;)
Non volevo scrivere un programma cobol, ma comprendere la natura
dell'affermazione iniziale. Ho sempre avuto questa presunzione, ma non
credo d'aver fatto passi avanti da quando accendevo un 3270 la mattina!
;)
Anche la JOIN che hai riportato d'esempio si avvantaggia di un indice
sulla FK immagino...
ciao a tutti

 ciao a tutti


In data Thu, 15 Jul 2004 19:06:00 +0200, Starsky ha scritto:
[cat]
Problema risolto, era decisamente banale: una delle 15 tabelle referenziate
era in realtà una view anch'essa, semplice (union tra due tabelle) ma con
molti più dati dal cliente che sulle mie macchina di test (dettaglio che mi
era sfuggito). Togliendo questa view e sostuitendo una tabella unica (in
modo che tutti i left join si riferissero a campi in chiave) il problema si
è risolto.
Grazie a tutti
Starsky