Scenario: SQL Server 2014 (v12.0.4100.1)
Il servizio .NET esegue questa query:
SELECT name, base_object_name
FROM sys.synonyms
WHERE schema_id IN (SELECT schema_id
FROM sys.schemas
WHERE name = N'XXXX')
ORDER BY name
... che restituisce circa 6500 righe ma spesso scade dopo 3+ minuti. Quanto XXXX
sopra non è 'dbo'.
Se eseguo questa query in SSMS come UtenteA, la query ritorna in meno di un secondo.
Quando eseguito come UserB (che è il modo in cui si connette il servizio .NET), la query richiede 3-6 minuti e ha la CPU% al 25% (di 4 core) per tutto il tempo.
UtenteA è un accesso al dominio nel ruolo di amministratore di sistema.
UserB è un login SQL con:
EXEC sp_addrolemember N'db_datareader', N'UserB'
EXEC sp_addrolemember N'db_datawriter', N'UserB'
EXEC sp_addrolemember N'db_ddladmin', N'UserB'
GRANT EXECUTE TO [UserB]
GRANT CREATE SCHEMA TO [UserB]
GRANT VIEW DEFINITION TO [UserB]
Posso duplicare questo in SSMS racchiudendo l'SQL sopra in un Execute as...Revert
blocco, quindi il codice .NET è fuori dall'immagine.
Il piano di esecuzione ha lo stesso aspetto. Ho diffuso l'XML e ci sono solo differenze minori (CompileTime, CompileCPU, CompileMemory).
Le statistiche IO non mostrano letture fisiche:
Tabella "sysobjvalues". Conteggio scansioni 0, letture logiche 19970, letture fisiche 0, letture avanti 0, letture logiche lob 0, letture fisiche lob 0, letture read lob 0. Tabella "File di lavoro". Conteggio scansioni 0, letture logiche 0, letture fisiche 0, letture read-ahead 0, letture logiche lob 0, letture fisiche lob 0, letture read lob 0. Tabella "Tavolo da lavoro". Conteggio scansioni 0, letture logiche 0, letture fisiche 0, letture read-ahead 0, letture logiche lob 0, letture fisiche lob 0, letture read lob 0. Tabella "sysschobjs". Conteggio scansione 1, letture logiche 9122, letture fisiche 0, letture read-ahead 0, letture log lob 0, letture fisiche lob 0, letture read lob 0. Tabella "sysclsobjs". Conteggio scansione 0, letture logiche 2, letture fisiche 0, letture read-ahead 0, letture logiche lob 0, letture fisiche lob 0, letture read lob 0.
XEvent attende lo stato (per una query di ~ 3min) sono:
+ --------------------- + ------------ + -------------- -------- + ------------------------------ + ---------- ------------------- + | Tipo di attesa | Attendi il conteggio | Tempo di attesa totale (ms) | Tempo di attesa totale delle risorse (ms) | Tempo di attesa del segnale totale (ms) | + --------------------- + ------------ + -------------- -------- + ------------------------------- + --------- -------------------- + | SOS_SCHEDULER_YIELD | 37300 | 427 | 20 | 407 | | NETWORK_IO | 5 | 26 | 26 | 0 | | IO_COMPLETION | 3 | 1 | 1 | 0 | + --------------------- + ------------ + -------------- -------- + ------------------------------- + --------- -------------------- +
Se riscrivo la query (in SSMS, non ho accesso al codice app) a
declare @id int
SELECT @id=schema_id FROM sys.schemas WHERE name = N'XXXX'
SELECT a.name, base_object_name FROM sys.synonyms a
WHERE schema_id = @id
ORDER BY name
quindi UserB funziona alla stessa velocità (veloce) di UserA.
Se aggiungo db_owner
a UserB, quindi, di nuovo, la query viene eseguita <1 sec.
Schema creato tramite questo modello:
DECLARE @TranName VARCHAR(20)
SELECT @TranName = 'MyTransaction'
BEGIN TRANSACTION @TranName
GO
IF NOT EXISTS (SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA
WHERE SCHEMA_NAME = '{1}')
BEGIN
EXEC('CREATE SCHEMA [{1}]')
EXEC sp_addextendedproperty @name='User', @value='{0}', @level0type=N'Schema', @level0name=N'{1}'
END
GO
{2}
COMMIT TRANSACTION MyTransaction;
GO
E {2} è, credo, un elenco di sinonimi creati in quello schema.
Profilo della query in due punti nella query:
Ho aperto un biglietto con Microsoft.
Inoltre, abbiamo provato ad aggiungere UserB db_owner
e quindi a DENY
tutti i privilegi a cui sappiamo che sono associati db_owner
. Il risultato è una query veloce. O abbiamo perso qualcosa (del tutto possibile) o c'è un controllo speciale per il db_owner
ruolo.