Una scansione costante richiede 0 secondi o 2-3 minuti


9

Una query come quella qui sotto che è garantita per non restituire alcuna riga, impiega da 0 a 160 secondi su uno dei nostri server:

select col1, col2, col3
from tab1
where 0 = 1

Due settimane fa, questo è successo sei volte in un intervallo di 48 ore. La scorsa settimana la stessa query ha richiesto ~ 0 secondi. Ho registri degli SQL della nostra applicazione ma non ho ancora trovato sospetti. Inoltre, ho pensato che una query di tipo 0 / dove 0 = 1 non raggiungesse mai le pagine di dati, quindi dovrebbe essere resistente ai blocchi di dati a livello di riga / pagina / tabella? Lo schema non viene toccato da alcun SQL (noto).

Poiché il problema non è coerente e il server è molto carico, vorrei capire la teoria alla base di ciò che sta accadendo prima di collegare il profiler SQL. Altre query vengono eseguite senza problemi durante questi ritardi. Un problema noto nell'applicazione è un numero elevato di query SQL create dinamicamente: circa 200k query uniche di 850k query (registrate) totali per un periodo di 48 ore, può causare problemi come questo?

Il server esegue SQL Server 2005 Standard Edition, 96 GB RAM, dischi su SAN e 4 CPU / 16 core. I file di database e i filegroup sono ben ottimizzati e non dovrebbero essere un problema (ma stiamo esaminando questo separatamente).

Qualsiasi suggerimento su cui guardare è molto apprezzato.

Modifica: perfetto! Ho riprodotto la query per aggiungere il piano di esecuzione e sono stati necessari 1 minuto e 35 secondi. Ecco il piano di esecuzione e lo screenshot che mostrano la durata della query: Piano di query

Modifica 2: dettagli tempo statistiche per una seconda corsa. Sembra essere costantemente lento in questo momento, quindi allegheremo profiler e perfmon:

SQL Server Execution Times:
   CPU time = 0 ms,  elapsed time = 97402 ms.
SQL Server parse and compile time: 
   CPU time = 0 ms, elapsed time = 0 ms.

Potresti per favore includere il piano di esecuzione? CTRL + M nella finestra della query prima dell'esecuzione.
Craig Efrein,

2
Potrebbe essere un problema di blocco? Istruzioni DML di altre sessioni che bloccano la selezione nella tabella (che è il comportamento predefinito in SQL Server 2005)
a_horse_with_no_name

Non ci sono dichiarazioni DML sconosciute, che è l'unica causa che mi viene in mente, ma stiamo ancora indagando su questo. Il piano di esecuzione viene aggiunto alla domanda.
EventHorizon

Da quello che ho letto, questo è solo uno di quei piani di esecuzione banali che MSSQL utilizza per evitare la lettura di heap e indici quando l'ottimizzatore sa che non ci sono righe da restituire
Craig Efrein

1
Ho visto un caso che assomigliava molto a questo. Si è scoperto che ha attivato le statistiche di aggiornamento (le statistiche di aggiornamento automatico sono state attivate e il piano di manutenzione è stato interrotto).
Giosuè,

Risposte:


18

Sembra che, anche con una ... WHERE 0 = 1clausola, ci sarà ancora un requisito per un ISblocco di intento shared ( ) sulla tabella. Dimostriamo questo:

Inizierò creando una tabella di prova:

use TestDb1;
go

create table dbo.MyTestTable1
(
    Id int identity(1, 1) not null,
    SomeInt int not null
);
go

insert into dbo.MyTestTable1 (SomeInt)
values (10), (20), (30), (40), (50);
go

Ora che ho la mia tabella di test, in una sessione (finestra della query) eseguirò quanto segue per attivare un Xblocco esclusivo ( ) dbo.MyTestTable1:

use TestDb1;
go

begin tran;
    select
        Id, SomeInt
    from dbo.MyTestTable1 with (tablockx);
--commit tran;

Posso verificare il blocco esclusivo guardando il sys.dm_tran_locksDMV. Quindi in un'altra sessione (nuova finestra di query) faccio esattamente ciò che fa la tua query:

use TestDb1;
go

select
    Id, SomeInt
from dbo.MyTestTable1
where 0 = 1;

A prima vista vedo che non sta completando. Guardando sys.dm_exec_requests, vedo esattamente perché questo è il caso:

select
    r.session_id,
    r.status,
    r.wait_type,
    r.wait_time,
    r.wait_resource,
    r.blocking_session_id
from sys.dm_exec_requests r
cross apply sys.dm_exec_sql_text(r.sql_handle) st
where st.text like '%where 0 = 1%'
and r.session_id <> @@spid;

inserisci qui la descrizione dell'immagine

Vedo qui che la mia ... WHERE 0 = 1query è in attesa di un ISblocco per questo oggetto (che object_id si traduce in dbo.MyTestTable1).

Non sto affatto dicendo che la concorrenza sia il tuo problema, ma dai suoni che stai manifestando i sintomi. L'esempio sopra è quello di dimostrare che non sei esente da blocco e blocco anche con una WHEREclausola che non restituirà mai i dati.

Tutto ciò che possiamo fare è indovinare, quindi quello che devi fare quando "impiega molto tempo" è vedere esattamente cosa sta facendo quella richiesta che impiega così tanto tempo. Se sta aspettando qualcosa, allora vedi cosa sta aspettando.


1

A seconda di quanto siano spinose e thread le tue query, il tuo sistema potrebbe semplicemente mettere in coda quella query. Il conteggio predefinito dei lavoratori (ovvero il numero di thread simultanei del server SQL) per la configurazione dovrebbe essere di circa 700.

Dai un'occhiata a sys.dm_os_schedulers e sys.dm_os_waiting_tasks per vedere se questo potrebbe essere un problema.


Un buon suggerimento, ma il problema alla fine è stato un blocco sciocco dopo tutto.
EventHorizon

Non ero davvero convinto, dal momento che 700 lavoratori sono molti, ma è stato facile controllare (e quindi escludere)
Sascha Rambeaud
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.