It is currently 26 September 2020, 1:35 Advanced search

TOP 1 fatale

Domande e risposte su come utilizzare Instant Developer Foundation al meglio

Re: TOP 1 fatale

Postby d.damico » 14 February 2020, 17:30

La tabella, in effetti non è una normale tabella ma una vista molto complessa.
Ma il punto non è questo. Quello che non capisco è questo. Ho scoperto due cose davvero assurde.
Il mio processore è uno Xeon 8-Core, la mia select sulla vista usando TOP(50) impiega circa un minuto.
Se da BIOS imposto la CPU per usare solo 4-Core il tempo pensate un po'.... scende a 25 secondi, ed è già assurdo così
Poi ho scoperto questo:
Se faccio
SELECT TOP 50 * FROM (SELECT * FROM LISTINI ORDER BY [CODART]) T1
Ci mette i famosi 25 secondi
Se invece faccio così
SELECT TOP 50 * FROM (SELECT TOP(9999999999) * FROM LISTINI ORDER BY [CODART]) T1
Ci mette 0 secondi, cioè è talmente veloce che il manager non riesce neanche a contare il primo secondo.
Quel TOP(9999999999) non dovrebbe fare un bel niente riguardo alle prestazioni dato che le righe che la mia select tira fuori sono circa 32000

Quindi che senso ha?!?!? Boh… io alzo le mani
d.damico
 
Posts: 244
Joined: 17 September 2019, 16:20

Re: TOP 1 fatale

Postby r.bianco » 17 February 2020, 7:43

Penso tu debba verificare il piano di esecuzione delle qry.
only work and no play makes jack a dull boy
r.bianco
 
Posts: 4196
Joined: 8 November 2010, 16:46

Re: TOP 1 fatale

Postby RB_82 » 17 February 2020, 7:48

hai provato a cercare/chiedere su Stack Overflow?
--
Riccardo B.
RB_82
 
Posts: 455
Joined: 23 June 2011, 12:44

Re: TOP 1 fatale

Postby smuser » 17 February 2020, 8:16

Sei sicuramente incappato in un problema di ottimizzazione della query.

Come saprai ogni db relazionale ha un ottimizzatore di query ovvero la select che tu scrivi viene tradotta prima dell'esecuzione.
Dato che lo scopo della traduzione dovrebbe essere quello di rendere la query più efficiente, eliminando ridondanze, utilizzando gli indici più opportuni, usando metodi di comparazione ottimizzati si parla di ottimizzazione.

L'algoritmo che decide l'ottimo lo fa secondo diversi criteri che cambiano da un dbms all'altro, dal tipo di installazione, dalle statistiche che il dbms raccoglie durante il normale utilizzo (quindi il comportamento può variare da un server all'altro a parità delle precedenti condizioni).

Guardare l'execution plan ti può aiutare a capire cosa sta facendo l'ottimizzatore ma potresti comunque avere difficoltà a capire il problema se non conosci come lavora (anche solo nella particolare situazione in cui sei).

Quando mi capita di solito seguo questo iter:
  • controlla tutte le tabelle coinvolte nella query:
    • numero di righe per tabella: l'ottimizzatore sotto un certo numero non usa l'indice ma cicla sui record della tabella
    • indici deframmentati: l'ottimizzatore non lo sa e lo usa anche se non è efficiente
    • presenza di campi lob: se nella select list porti molti campi e/o di grosse dimensioni potresti incorrere in problemi di cache
  • intraprendi delle azioni correttive e ad ogni azione riesegui la query e controlla se l'execution plan cambia: quando cambia vai a cercare nella documentazione del dbms il comportamento legato all'azione che ha modificato il plan

Spesso mi è capitato di riscontrare problemi legati alla query e agli indici, altre volte era un problema di configurazione (parametri di caching), altre volte un bug dell'ottimizzatore, poche volte problemi dell'host.
User avatar
smuser
 
Posts: 193
Joined: 3 May 2019, 10:41
Location: Milano

Re: TOP 1 fatale

Postby d.damico » 17 February 2020, 18:58

>Sei sicuramente incappato in un problema di ottimizzazione della query.
Si, in effetti migliorando la vista i tempi sono scesi drasticamente, ma comunque sono troppo alti.
Ma una cosa proprio non me la spiego. Lo stesso DB messo su macchine meno potenti risponde ISTANTANEAMENTE alla select
Ho provato su tre server diversi. Su due 4 core la query è velocissima, e non è l'unica, nel senso che anche altre query hanno lo stesso rallentamento solo che una in particolare è macroscopicamente più lenta.
Su questo server 8 core ho questi tempi lunghissimi, il processore schizza al 100% per 30 secondi e la ventola accelera.
Ma se da bios gli dico che il processore deve lavorare in 4 cores ecco che stesso db, stesse querry... e stessi errori di ottimizzazione... diventano nulla e tutto diventa velocissimo ed istantaneo.

Questo è un mistero pazzesco per me.
d.damico
 
Posts: 244
Joined: 17 September 2019, 16:20

Re: TOP 1 fatale

Postby RB_82 » 18 February 2020, 8:04

Leggermente OT
SQL Server è un ottimo db ma a volte fa cose veramente strane.
Basta pensare all'annoso problema del "parameter sniffing" che affossa le prestazioni di query con i parametri.
Ho di recente modificato delle query di inde che usavano i parametri, togliendoglieli ottenendo incrementi prestazionali dell'ordine del 900%.
A volte vorrei capire quale sarebbe la differenza prestazionale senza l'analisi statistica e la progettazione di un piano di esecuzione personalizzato per query.
--
Riccardo B.
RB_82
 
Posts: 455
Joined: 23 June 2011, 12:44

Re: TOP 1 fatale

Postby d.damico » 18 February 2020, 8:15

Il problema l'ho risolto, ma non so davvero dare una spiegazione ingegneristica.
Ho aumentato il parametro Cost Threshold for Parallelism da 5 (il default) a 50
Adesso va che è una scheggia.
Questo perchè inspiegabilmente alcune query se eseguite su un solo core va una scheggia, se eseguite in parallelo, quindi implica più core mi satura tutti i core per decine e decine di secondi.
Incredibile.
d.damico
 
Posts: 244
Joined: 17 September 2019, 16:20

Re: TOP 1 fatale

Postby smuser » 18 February 2020, 14:02

Bravo e grazie per aver condiviso la soluzione.
Ho letto un po' di cose sul parametro che hai modificato e molti concordano nel portarlo da 5 a 50 come hai fatto tu. La cosa che mi lascia dei dubbi è che lo stesso db su altre macchine meno potenti non ha problemi sulla select incriminata.

Prima di considerare chiusa la questione valuterei che non ci sia un problema di rebuild degli indici e delle statistiche del db.

Il parametro CTP è il costo della query considerato come soglia per decidere tra un'esecuzione con piano seriale o un'esecuzione con piano parallelo.
Dato che l'ottimizzatore valuta il costo della query da eseguire in funzione delle statistiche delle tabelle coinvolte nella query sembra che stia stimando male i costi.
Se sulla macchina meno potente la query va bene, il motivo potrebbe essere che durante il porting del db da un server ad un altro le statistiche vengano ricalcolate.

Se hai tempo fai un tentativo: rimetti il parametro CTP da 50 a 5, rebuild indici e update statistics fullscan delle tabelle coinvolte nella select, esegui la query 2-3 volte.
User avatar
smuser
 
Posts: 193
Joined: 3 May 2019, 10:41
Location: Milano

Re: TOP 1 fatale

Postby d.damico » 18 February 2020, 14:24

>Se hai tempo fai un tentativo: rimetti il parametro CTP da 50 a 5, rebuild indici e update statistics fullscan delle tabelle coinvolte nella select
Purtroppo, quando migro un DB queste sono sempre le prime cose che faccio. Quindi il problema non è qui, garantisco.
Comunque, un'altro modo che avevo trovato, addirittura non richiede nemmeno di toccarlo il DB.
Nel senso che mi bastava andare sul BIOS del server ed abilitare solo 4 core invece di 8 e diventava subito velocissimo.
d.damico
 
Posts: 244
Joined: 17 September 2019, 16:20

Re: TOP 1 fatale

Postby smuser » 19 February 2020, 8:10

Ok allora deve trattarsi di un problema dell'ottimizzatore per la particolare architettura.
Se e quando ti va mi manderesti il risultato di questa query?

Code: Select all
SELECT 
cpu_count AS logicalCPUs,
hyperthread_ratio,
softnuma_configuration,
cores_per_socket,
numa_node_count 
FROM sys.dm_os_sys_info;


Grazie
SM
User avatar
smuser
 
Posts: 193
Joined: 3 May 2019, 10:41
Location: Milano

PreviousNext

Return to Tips & Tricks - Foundation

Who is online

Users browsing this forum: No registered users and 18 guests

cron