Viele "FETCH API_CURSOR0000 ..." auf sp_WhoIsActive (SQL Server 2008 R2)

9

Ich habe eine seltsame Situation. Mit sp_whoisactivekann ich das sehen:

Seltsam

Ok, mit dieser Abfrage kann ich sehen, was auslöst (existiert dieses Wort auf Englisch?) Es:

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

das Ergebnis:

Es ist nur eine Auswahl

es ist einfach select. Warum wird f verwendet etch_cursor?

Außerdem sehe ich auch viele "leere" sql_texts. Hat das etwas mit diesem "Cursor" zu tun?

leer

DBCC INPUTBUFFER (spid) zeigt mir das:

drucken

Es gibt diese Frage hier (von mir gemacht), aber ich weiß nicht, ob das das gleiche ist.


EDIT1:

Bei Verwendung der von kin bereitgestellten Abfrage sehe ich Folgendes:

immer noch kein Code.


EDIT2:

Mit dem Aktivitätsmonitor kann ich Folgendes sehen:

Mos teure Abfrage

Es ist die teuerste Abfrage (Die erste ist beabsichtigt, wir wissen davon).

Und wieder möchte ich wissen, warum dies select * from...der Grund für FETCH CURSOR...


EDIT3:

Dieses " select * from..." läuft von einem anderen Server (via linked server).

Nun, jetzt habe ich Probleme zu verstehen, was @kin gesagt hat.

Dies ist die execution planAbfrage (die auf demselben Server der Datenbank ausgeführt wird):

gleicher Server der Datenbank

Dies ist nun der Ausführungsplan, der auf dem anderen Server über den Verbindungsserver ausgeführt wird:

Geben Sie hier die Bildbeschreibung ein

Ok, auch kein Problem. Und nun! der Ausführungsplan über **activity monitor**(das gleiche select * from):

Was zur Hölle geht hier vor?

Racer SQL
quelle

Antworten:

3

Es ist eine einfache Auswahl. Warum wird fetch_cursor verwendet?

Das SELECTwird vom Framework für verteilte Abfragen vom System generiert und ist mit dem UPDATEgefundenen verknüpft .

Der Abfrageplanoperator für Remote-Aktualisierung verwendet das sp_cursorModell, um Zeilen aus der Remote-Datenquelle abzurufen. Dies ist die Ursache für alle Cursor-API-Aufrufe.

Ich glaube, der Cursorplan, den Sie in Ihrer Frage anzeigen, ist der interne Cursor, den die Engine im Rahmen dieses Prozesses geöffnet hat, aber ich hatte noch keine Zeit, dies zu reproduzieren.

Paul White 9
quelle
1

Dies kann ein Problem bei OLEDB-Aufrufen an Remoteserver sein (Verbindungsserver und SSIS-Konfigurationen verwenden OLEDB).

Dies ist ein Konstruktionsfehler, ein Microsoft SQL Server-Fehler, der erst nach SQL Server 2012 SP1 behoben wurde, soweit ich mich erinnere, dass Remote-Statistiken nicht zur Remote-Optimierung der Abfrage verwendet werden können.

Sie müssen sp_WhoIsActive ( download | docs ) auch vom REMOTE-Server in der Abfrage ausführen, um den Datenverkehr anzuzeigen. SQL Server, der nicht 2012 SP1 ist, erlaubt jedoch aus irgendeinem Grund die Verwendung von Remotestatistiken, selbst wenn die Anmeldung über einen Datenleser verfügt Zugriff auf alle Tabellen auf dem Remote-Server.

Die Microsoft-Lösung besteht darin, dem Verbindungsserver-Berechtigungsnachweis, mit dem der Remote-Aufruf ausgeführt wird, SA- oder ddladmin- oder DBO-Zugriff auf die abgefragten Remote-Server / -Tabellen zu gewähren.

Ich habe dies verwendet, um dieses Problem in einigen unserer Setups zu umgehen, das größtenteils lösungsmäßig transparent ist, ohne erhöhte Berechtigungen für DBs oder SQL Server auf der Remote-Seite zuzulassen. Grundsätzlich müssen Sie die Remote-Login-Rolle ddladmin in der betreffenden Remote-SQL Server-Datenbank gewähren und dann eine Rolle mit expliziten DENY-Berechtigungen für die Änderungen auf Objektebene erstellen, wenn Sie nur den SELECT-Zugriff zulassen möchten.

Unten finden Sie die Kopie der benutzerdefinierten DB-festen Rolle, die ich dafür erstellt habe. Möglicherweise möchten Sie diese testen und bestätigen oder weiter anpassen sowie einige Lese- und Recherchevorgänge durchführen, die jedoch in einigen Fällen für mich transparent aufgelöst wurden. Möglicherweise muss der Cache jedoch gelöscht werden, bevor dies funktioniert Denken Sie daran, und führen Sie es nach dem Löschen zweimal aus und überprüfen Sie sowohl die lokale Aktivität als auch die Remote-Aktivität auf Ergebnisse.

Erlauben Sie dem Berechtigungsnachweis die ddladmin-Rolle in der Remote-Datenbank, Sie erlauben die anderen üblichen Berechtigungen in der Remote-Datenbank, Sie erstellen die benutzerdefinierte DB-Rolle, wie unten aufgeführt, auf demselben Server und fügen dann denselben Berechtigungsnachweis zu diesem neuen benutzerdefinierten Fix hinzu DB-Rolle mit den expliziten Ablehnungen, löschen Sie den Cache, führen Sie die Abfrage zweimal oder öfter aus, nachdem Sie den Cache geleert haben, um zu sehen, ob sie aufgelöst wird.

Um Ihre Frage jedoch speziell zu beantworten, weil diese Cursorabrufe angezeigt werden, wenn Sie eine Version unter SQL Server 2012 SP1 ausführen und dies sehen und eine Remote-Abfrage ausführen, da die Verwendung oder Remote nicht zulässig ist Statistiken in diesem Setup ohne Problemumgehung (wie oben aufgeführt), führt dann die zeilenweise Verarbeitung wie oben angegeben durch, da die Abfrage nicht mithilfe von Statistiken für den besten Abfrageplan optimiert wurde und das Kardinalitätsproblem aufweist.

/* 
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
Zuhälter Saft IT
quelle
1

Nun ... Wir haben das Problem gelöst. Innerhalb der ausgeführten Prozedur gab es ein Update, das "select * from ..." ausführte. Ich habe das Update kommentiert. keine Probleme mehr.

Racer SQL
quelle