Muitos "FETCH API_CURSOR0000…" em sp_WhoIsActive (SQL Server 2008 R2)

9

Eu tenho uma situação estranha. Usando sp_whoisactiveeu posso ver isso:

Estranho

Ok, com esta consulta, posso ver o que está acionando (esta palavra existe em 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

o resultado:

é apenas uma seleção

é simples select. Por que isso está usando f etch_cursor?

Além disso, também vejo muitos sql_texts "em branco". Isso tem algo com esse "cursor"?

em branco

DBCC INPUTBUFFER (spid) mostra-me isto:

impressão

Aqui está essa pergunta (feita por mim), mas não sei se é a mesma coisa.


EDIT1:

Usando a consulta fornecida por parentes, vejo o seguinte:

ainda sem código.


EDIT2:

Usando o Activity Monitor, posso ver isso:

Minha consulta cara

É a consulta mais cara (a primeira é intencional, sabemos disso).

E, novamente, gostaria de saber por que esse select * from...é o motivo de FETCH CURSOR...


EDIT3:

Este " select * from..." está sendo executado em outro servidor (via linked server).

Bem, agora estou tendo problemas para entender o que @kin disse.

Este é o execution planda consulta (em execução no mesmo servidor do banco de dados):

mesmo servidor do banco de dados

agora é o plano de execução em execução no outro servidor, via servidor vinculado:

insira a descrição da imagem aqui

Ok, também não é um problema. E agora! o plano de execução, via **activity monitor**(o mesmo select * from):

Que diabos está acontecendo aqui?

Racer SQL
fonte

Respostas:

3

É uma seleção simples. Por que isso está usando fetch_cursor?

O SELECTsistema é gerado pela estrutura do Distributed Query e está associado ao que UPDATEvocê encontrou.

O operador do plano de consulta Atualização Remota usa o sp_cursormodelo para buscar linhas da fonte de dados remota. Essa é a causa de todas as chamadas da API do cursor.

Acredito que o plano do cursor que você mostra na sua pergunta seja o cursor interno aberto pelo mecanismo como parte desse processo, mas ainda não tive tempo de tentar reproduzir isso.

Paul White 9
fonte
1

Isso pode ser um problema nas chamadas OLEDB para servidores remotos (servidores vinculados e configurações SSIS usam OLEDB).

Esta é uma falha de design, erro do Microsoft SQL Server que não foi corrigido até o SQL Server 2012 SP1, pelo que me lembro onde não permite que estatísticas remotas sejam usadas para otimizar remotamente a consulta.

Você precisará executar sp_WhoIsActive ( download | docs ) no servidor REMOTE na consulta também para ver o tráfego, mas o SQL Server que não é o 2012 SP1 não permite o uso de estatísticas remotas por algum motivo, mesmo que o login tenha o datareader acesso a todas as tabelas no servidor remoto.

A solução da Microsoft é conceder à credencial do servidor vinculado que está fazendo a chamada remota acesso SA, ou ddladmin ou DBO aos servidores / tabelas remotos que estão sendo consultados.

Usei isso para solucionar esse problema em algumas de nossas configurações, que são transparentes para a maior parte das soluções, sem permitir permissões elevadas para bancos de dados ou servidores SQL no lado remoto. Basicamente, você precisa conceder a função ddladmin de logon remoto no banco de dados remoto do SQL Server em questão e, em seguida, criar uma função com permissões DENY explícitas para as alterações no nível do objeto se você deseja permitir o acesso SELECT.

Abaixo está a cópia da função fixa do banco de dados personalizada que eu crio para isso, mas você pode querer testar e confirmar ou ajustar ainda mais algumas leituras e pesquisas, mas resolvidas de forma transparente para mim em alguns casos - o cache pode precisar ser limpo antes de funcionar, portanto lembre-se disso e, uma vez limpo, execute-o duas vezes e verifique a atividade local e a atividade remota para obter resultados.

Portanto, permita à credencial a função ddladmin no banco de dados remoto, permita as outras permissões usuais no banco de dados remoto, crie a função de banco de dados personalizada conforme listado abaixo neste mesmo servidor e adicione a mesma credencial à nova solução fixa personalizada A função do banco de dados com as negações explícitas, limpa o cache, executa a consulta duas ou mais vezes após limpar o cache para verificar se ele é resolvido.

Para responder especificamente à sua pergunta, pelo motivo de você estar vendo esses cursores, se estiver executando uma versão abaixo do SQL Server 2012 SP1 e vendo isso e estiver executando uma consulta remota, porque ela não permite o uso ou remota estatísticas nesta configuração sem uma solução alternativa (conforme listado acima), ele realiza o processamento linha a linha como o Kin afirmou acima, pois a consulta não é otimizada usando estatísticas para o melhor plano de consulta e tem o problema de cardinalidade.

/* 
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
fonte
1

Bem ... resolvemos o problema. Houve uma atualização, dentro do procedimento em execução que "selecione * de ...". Eu comentei a atualização. sem mais problemas.

Racer SQL
fonte