Un montón de "FETCH API_CURSOR0000 ..." en sp_WhoIsActive (SQL Server 2008 R2)

9

Tengo una situación extraña Usando sp_whoisactivepuedo ver esto:

Extraño

Ok, con esta consulta, puedo ver lo que está provocando (¿existe esta palabra en inglés?):

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

el resultado:

es solo un selecto

Es un simple select. ¿Por qué está usando f etch_cursor?

Además, también veo muchos sql_texts "en blanco". ¿Esto tiene algo con este "cursor"?

blanco

DBCC INPUTBUFFER (spid) me muestra esto:

impresión

Hay esta pregunta aquí (hecha por mí) pero no sé si esto es lo mismo.


EDITAR1:

Usando la consulta proporcionada por kin, veo esto:

Todavía no hay código.


EDIT2:

Usando Activity Monitor, puedo ver esto:

Consulta más cara

Es la consulta más cara (la primera es intencional, lo sabemos).

Y nuevamente, me gustaría saber por qué esta select * from...es la razón de FETCH CURSOR...


EDITAR3:

Este " select * from..." se ejecuta desde otro servidor (a través de linked server).

Bueno, ahora tengo problemas para entender lo que dijo @kin.

Este es el execution plande la consulta (ejecutándose en el mismo servidor de la base de datos):

mismo servidor de la base de datos

ahora es el plan de ejecución, que se ejecuta en el otro servidor, a través del servidor vinculado:

ingrese la descripción de la imagen aquí

Ok, no es un problema también. ¡Y ahora! El plan de ejecución, vía **activity monitor**(el mismo select * from):

¿Qué diablos está pasando aquí?

Racer SQL
fuente

Respuestas:

3

Es una simple selección. ¿Por qué está usando fetch_cursor?

El SELECTsistema lo genera el marco de consulta distribuida y está asociado con el UPDATEque encontró.

El operador del plan de consulta Actualización remota usa el sp_cursormodelo para recuperar filas del origen de datos remoto. Esta es la causa de todas las llamadas a la API del cursor.

Creo que el plan de cursor que muestra en su pregunta es el cursor interno abierto por el motor como parte de este proceso, pero todavía no he tenido tiempo de intentar reproducirlo.

Paul White 9
fuente
1

Esto puede ser un problema con las llamadas OLEDB a servidores remotos (los servidores vinculados y las configuraciones SSIS usan OLEDB).

Este es un error de diseño, error de Microsoft SQL Server que no fue parcheado hasta SQL Server 2012 SP1 por lo que recuerdo, donde no permite que se usen estadísticas remotas para optimizar la consulta de forma remota.

Deberá ejecutar sp_WhoIsActive ( descargar | documentos ) desde el servidor REMOTO en la consulta también para ver el tráfico, pero SQL Server que no es 2012 SP1 no permite el uso de estadísticas remotas por alguna razón, incluso si el inicio de sesión tiene un lector de datos acceso a todas las tablas en el servidor remoto.

La solución de Microsoft es otorgar a la credencial del servidor vinculado que la llamada remota tenga acceso SA, o ddladmin o DBO al servidor / tabla (s) remota (s) que se consultan.

Utilicé esto para solucionar este problema en algunas de nuestras configuraciones, que es transparente en su mayor parte en cuanto a la solución, sin permitir permisos elevados para DB o servidores SQL en el lado remoto. Básicamente, debe otorgar la función de inicio de sesión remoto ddladmin en la base de datos remota de SQL Server en cuestión y luego crear una función con permisos explícitos DENY para los cambios a nivel de objeto si solo tiene la intención de permitir el acceso SELECCIONAR.

A continuación se muestra la copia de la función fija de base de datos personalizada que creo para esto, pero es posible que desee probar y confirmar o ajustar más, además de algunas lecturas e investigaciones, pero se resolvió de manera transparente para mí en algunos casos; es posible que el caché necesite borrarse antes de que funcione. tenga esto en cuenta y una vez que se borre, ejecútelo dos veces y verifique la actividad local y la actividad remota para obtener resultados.

Entonces, permita la credencial de la función ddladmin en la base de datos remota, permita los otros permisos habituales en la base de datos remota, cree la función de base de datos personalizada como se enumera a continuación en este mismo servidor y luego agregue esa misma credencial a esa nueva solución personalizada El rol de base de datos con las negaciones explícitas, borra el caché, ejecuta la consulta dos veces o más después de borrar el caché para ver si se resuelve.

Sin embargo, para responder específicamente a su pregunta por la razón por la que está viendo estas recuperaciones de cursor, si está ejecutando una versión por debajo de SQL Server 2012 SP1 y está viendo esto y está ejecutando una consulta remota, porque no permite el uso o estadísticas en esta configuración sin una solución alternativa (como se enumeró anteriormente), luego realiza el procesamiento fila por fila como Kin indicó anteriormente, ya que la consulta no está optimizada usando estadísticas para el mejor plan de consulta y tiene el problema de cardinalidad.

/* 
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
Pimp Juice IT
fuente
1

Bueno ... Resolvimos el problema. Hubo una actualización, dentro del procedimiento en ejecución que "selecciona * de ...". Comenté la actualización. No más problemas.

Racer SQL
fuente