Szenario: SQL Server 2014 (v12.0.4100.1)
Der .NET-Dienst führt diese Abfrage aus:
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
... was ungefähr 6500 Zeilen zurückgibt, aber oft nach mehr als 3 Minuten eine Zeitüberschreitung aufweist. Das XXXXobige ist nicht 'dbo'.
Wenn ich diese Abfrage in SSMS als UserA ausführe, wird die Abfrage in weniger als einer Sekunde zurückgegeben.
Bei Ausführung als UserB (wie der .NET-Dienst eine Verbindung herstellt) dauert die Abfrage 3-6 Minuten und die CPU% liegt die ganze Zeit über bei 25% (von 4 Kernen).
UserA ist eine Domänenanmeldung in der Sysadmin-Rolle.
UserB ist ein SQL Login mit:
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]
Ich kann dies in SSMS duplizieren, indem ich das obige SQL in einen Execute as...RevertBlock einbinde , sodass der .NET-Code nicht im Bild ist.
Der Ausführungsplan sieht gleich aus. Ich habe das XML unterschieden und es gibt nur geringfügige Unterschiede (CompileTime, CompileCPU, CompileMemory).
Alle E / A-Statistiken zeigen keine physischen Lesevorgänge an:
Tabelle 'sysobjvalues'. Scananzahl 0, logische Lesevorgänge 19970, physische Lesevorgänge 0, Vorauslesevorgänge 0, Lob-Lesevorgänge 0, Lob-Lesevorgänge 0, Lobvorlesevorgänge 0. Tabelle 'Arbeitsdatei'. Scananzahl 0, logische Lesevorgänge 0, physische Lesevorgänge 0, Vorauslesevorgänge 0, Lob-Lesevorgänge 0, Lob-Lesevorgänge 0, Lobvorlesevorgänge 0. Tabelle 'Arbeitstisch'. Scananzahl 0, logische Lesevorgänge 0, physische Lesevorgänge 0, Vorauslesevorgänge 0, Lob-Lesevorgänge 0, Lob-Lesevorgänge 0, Lobvorlesevorgänge 0. Tabelle 'sysschobjs'. Scananzahl 1, logische Lesevorgänge 9122, physische Lesevorgänge 0, Vorauslesevorgänge 0, Lob-Lesevorgänge 0, Lob-Lesevorgänge 0, Lobvorlesevorgänge 0. Tabelle 'sysclsobjs'. Scananzahl 0, logische Lesevorgänge 2, physische Lesevorgänge 0, Vorauslesevorgänge 0, Lob-Lesevorgänge 0, Lob-Lesevorgänge 0, Lobvorlesevorgänge 0.
Der Status von XEvent wartet (für eine ~ 3-minütige Abfrage):
+ --------------------- + ------------ + -------------- -------- + ------------------------------ + ---------- ------------------- + | Warten Sie Typ | Warte Zählung | Gesamtwartezeit (ms) | Wartezeit der gesamten Ressource (ms) | Gesamtsignalwartezeit (ms) | + --------------------- + ------------ + -------------- -------- + ------------------------------- + --------- -------------------- + | SOS_SCHEDULER_YIELD | 37300 | 427 | 20 | 407 | | NETWORK_IO | 5 | 26 | 26 | 0 | | IO_COMPLETION | 3 | 1 | 1 | 0 | + --------------------- + ------------ + -------------- -------- + ------------------------------- + --------- -------------------- +
Wenn ich die Abfrage neu schreibe (in SSMS habe ich keinen Zugriff auf den App-Code) an
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
dann läuft UserB mit der gleichen (schnellen) Geschwindigkeit wie UserA.
Wenn ich db_ownerzu UserB hinzufüge , wird die Abfrage erneut <1 Sek. Ausgeführt.
Über diese Vorlage erstelltes Schema:
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
Und {2} ist meiner Meinung nach eine Liste von Synonymen, die in diesem Schema erstellt wurden.
Abfrageprofil an zwei Stellen in der Abfrage:
Ich habe ein Ticket bei Microsoft geöffnet.
Außerdem haben wir versucht, UserB hinzuzufügen db_ownerund dann DENYalle uns bekannten Berechtigungen zu verwenden, die damit verbunden sind db_owner. Das Ergebnis ist eine schnelle Abfrage. Entweder haben wir etwas verpasst (durchaus möglich) oder es gibt eine spezielle Überprüfung für die db_ownerRolle.





