Molti "FETCH API_CURSOR0000 ..." su sp_WhoIsActive (SQL Server 2008 R2)


9

Ho una strana situazione. Usando sp_whoisactiveposso vedere questo:

Strano

Ok, con questa query, posso vedere cosa sta scatenando (questa parola esiste in inglese?):

SELECT c.session_id, c.properties, c.creation_time, c.is_open, t.text
FROM sys.dm_exec_cursors (SPID) c --0 for all cursors running
CROSS APPLY sys.dm_exec_sql_text (c.sql_handle) t

il risultato:

è solo una scelta

è un semplice select. Perché sta usando f etch_cursor?

Inoltre, vedo molti sql_texts "vuoti". Questo ha qualcosa con questo "cursore"?

vuoto

DBCC INPUTBUFFER (spid) mi mostra questo:

Stampa

c'è questa domanda qui (fatta da me) ma non so se questa è la stessa cosa.


Edit1:

Utilizzando la query fornita da kin, vedo questo:

ancora nessun codice.


EDIT2:

Utilizzando Activity Monitor, posso vedere questo:

Query Mos costoso

È la query più costosa (la prima è intenzionale, lo sappiamo).

E ancora, vorrei sapere, perché questa select * from...è la ragione di FETCH CURSOR...


Edit3:

Questo " select * from..." è in esecuzione da un altro server (via linked server).

Bene, ora ho problemi a capire cosa ha detto @kin.

Questo è il execution plandella query (in esecuzione nello stesso server del database):

stesso server del database

questo è ora, il piano di esecuzione, in esecuzione nell'altro server, tramite server collegato:

inserisci qui la descrizione dell'immagine

Ok, non è un problema. E adesso! il piano di esecuzione, tramite **activity monitor**(lo stesso select * from):

che diavolo sta succedendo qui?

Risposte:


3

È una scelta semplice. Perché sta usando fetch_cursor?

Il SELECTsistema è generato dal framework Query distribuita ed è associato al sistema UPDATEtrovato.

L'operatore del piano di query di aggiornamento remoto utilizza il sp_cursormodello per recuperare le righe dall'origine dati remota. Questa è la causa di tutte le chiamate API del cursore.

Credo che il piano del cursore che mostri nella tua domanda sia il cursore interno aperto dal motore come parte di questo processo, ma non ho ancora avuto il tempo di provare a riprodurlo.


1

Questo potrebbe essere un problema con le chiamate OLEDB ai server remoti (i server collegati e le configurazioni SSIS utilizzano OLEDB).

Questo è un difetto di progettazione, bug di Microsoft SQL Server che non è stato corretto fino a SQL Server 2012 SP1 da quello che ricordo dove non consente l'utilizzo di statistiche remote per ottimizzare la query in remoto.

Sarà necessario eseguire sp_WhoIsActive ( download | docs ) dal server REMOTE nella query anche per visualizzare il traffico, ma SQL Server che non è SP1 2012 non consente l'uso di statistiche remote per qualche motivo anche se il login ha datareader accesso a tutte le tabelle sul server remoto.

La soluzione Microsoft consiste nel concedere le credenziali del server collegato effettuando la chiamata remota in modo da disporre dell'accesso SA, ddladmin o DBO al server / alle tabelle remoti.

Ho usato questo per risolvere questo problema in alcune delle nostre configurazioni, che è trasparente per la maggior parte della soluzione saggia senza consentire autorizzazioni elevate per DB o server SQL sul lato remoto. Fondamentalmente è necessario concedere il ruolo ddladmin di accesso remoto sul DB di SQL Server remoto in questione, quindi creare un ruolo con autorizzazioni DENY esplicite per le modifiche a livello di oggetto se si intende solo consentire l'accesso SELECT.

Di seguito è riportata la copia del ruolo fisso DB personalizzato che creo per questo, ma potresti voler testare e confermare o regolare ulteriormente oltre a leggere e ricercare, ma risolto in modo trasparente per me in alcuni casi - la cache potrebbe aver bisogno di essere svuotata anche se prima di funzionare così tienilo a mente e una volta cancellato, eseguilo due volte e controlla sia l'attività locale che l'attività remota per i risultati.

Quindi consenti alle credenziali il ruolo ddladmin sul DB remoto, consenti le altre consuete autorizzazioni sul DB remoto, crei il ruolo DB personalizzato come elencato di seguito su questo stesso server e quindi aggiungi la stessa credenziale a quella nuova fissa personalizzata Ruolo DB con esplicito rifiuto, svuota la cache, esegui la query due o più volte dopo aver svuotato la cache per vedere se si risolve.

Per rispondere in modo specifico alla tua domanda, anche se per il motivo che vedi questi recuperi del cursore, se stai eseguendo una versione inferiore a SQL Server 2012 SP1 e stai vedendo questo e stai eseguendo una query remota, perché non consente l'utilizzo o remoto le statistiche in questa configurazione senza una soluzione alternativa (come elencato sopra), quindi esegue l'elaborazione riga per riga come indicato in precedenza Kin poiché la query non è ottimizzata utilizzando le statistiche per il miglior piano di query e presenta il problema di cardinalità.

/* 
CREATE A NEW ROLE - Deny explicit DB object access for linked 
server credentials that the DDLAdmin role gives which is needed 
for DBCC SHOW_STATISTICS across linked servers  
*/
-- Database specific
CREATE ROLE db_LinkedServer_Restriction
DENY ALTER ANY ASSEMBLY                    TO db_LinkedServer_Restriction
DENY ALTER ANY ASYMMETRIC KEY              TO db_LinkedServer_Restriction
DENY ALTER ANY CERTIFICATE                 TO db_LinkedServer_Restriction
DENY ALTER ANY CONTRACT                    TO db_LinkedServer_Restriction
DENY ALTER ANY DATABASE DDL TRIGGER        TO db_LinkedServer_Restriction
DENY ALTER ANY DATABASE EVENT NOTIFICATION TO db_LinkedServer_Restriction
DENY ALTER ANY DATASPACE                   TO db_LinkedServer_Restriction
DENY ALTER ANY FULLTEXT CATALOG            TO db_LinkedServer_Restriction
DENY ALTER ANY MESSAGE TYPE                TO db_LinkedServer_Restriction
DENY ALTER ANY REMOTE SERVICE BINDING      TO db_LinkedServer_Restriction
DENY ALTER ANY ROUTE                       TO db_LinkedServer_Restriction
DENY ALTER ANY SCHEMA                      TO db_LinkedServer_Restriction
DENY ALTER ANY SERVICE                     TO db_LinkedServer_Restriction
DENY ALTER ANY SYMMETRIC KEY               TO db_LinkedServer_Restriction
DENY CHECKPOINT                            TO db_LinkedServer_Restriction
DENY CREATE AGGREGATE                      TO db_LinkedServer_Restriction
DENY CREATE DEFAULT                        TO db_LinkedServer_Restriction
DENY CREATE FUNCTION                       TO db_LinkedServer_Restriction
DENY CREATE PROCEDURE                      TO db_LinkedServer_Restriction
DENY CREATE QUEUE                          TO db_LinkedServer_Restriction
DENY CREATE RULE                           TO db_LinkedServer_Restriction
DENY CREATE SYNONYM                        TO db_LinkedServer_Restriction
DENY CREATE TABLE                          TO db_LinkedServer_Restriction
DENY CREATE TYPE                           TO db_LinkedServer_Restriction
DENY CREATE VIEW                           TO db_LinkedServer_Restriction
DENY CREATE XML SCHEMA COLLECTION          TO db_LinkedServer_Restriction
DENY REFERENCES                            TO db_LinkedServer_Restriction

GO

1

Bene ... abbiamo risolto il problema. C'è stato un aggiornamento, all'interno della procedura in esecuzione che "seleziona * da ...". Ho commentato l'aggiornamento. niente più problemi.

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.