Много «FETCH API_CURSOR0000…» на sp_WhoIsActive (SQL Server 2008 R2)


9

У меня странная ситуация. Используя sp_whoisactiveя могу видеть это:

Странный

Хорошо, с помощью этого запроса я вижу, что вызывает (существует ли это слово на английском языке?):

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

результат:

это просто выбор

это просто select. Почему это использует F etch_cursor?

Также я вижу много «пустых» sql_texts. Это имеет что-то с этим "курсором"?

пустой

DBCC INPUTBUFFER (spid) показывает мне это:

Распечатать

есть этот вопрос здесь (сделанный мной) , но я не знаю , если это то же самое.


EDIT1:

Используя запрос, предоставленный kin, я вижу это:

до сих пор нет кода.


EDIT2:

Используя Activity Monitor, я вижу это:

Мос дорогой запрос

Это самый дорогой запрос (первый - преднамеренный, мы знаем об этом).

И еще раз, я хотел бы знать, почему это select * from...является причиной FETCH CURSOR...


EDIT3:

Это " select * from..." выполняется с другого сервера (через linked server).

Ну, теперь у меня проблемы с пониманием того, что сказал @kin.

Это execution planзапрос (работает на том же сервере базы данных):

тот же сервер базы данных

теперь это план выполнения, выполняемый на другом сервере через связанный сервер:

введите описание изображения здесь

Ок, тоже не проблема. И сейчас! план выполнения, через **activity monitor**(тот же select * from):

Что, черт возьми, здесь происходит?

Ответы:


3

Это простой выбор. Почему это использует fetch_cursor?

Он SELECTгенерируется системой средой распределенного запроса и связан с UPDATEнайденным вами.

Оператор плана запросов удаленного обновления использует sp_cursorмодель для выборки строк из удаленного источника данных. Это является причиной всех вызовов API курсора.

Я полагаю, что план курсора, который вы показываете в своем вопросе, является внутренним курсором, открытым движком как часть этого процесса, но у меня еще не было времени попытаться воспроизвести это.


1

Это может быть проблемой с вызовами OLEDB к удаленным серверам (связанные серверы и конфигурации SSIS используют OLEDB).

Это конструктивный недостаток, ошибка Microsoft SQL Server, которая не была исправлена ​​до SQL Server 2012 SP1, поскольку, насколько я помню, она не позволяет использовать удаленную статистику для удаленной оптимизации запроса.

Вам также потребуется запустить sp_WhoIsActive ( download | docs ) с удаленного сервера в запросе, чтобы увидеть трафик, но SQL Server, отличающийся от 2012 SP1, по какой-то причине не позволяет использовать удаленную статистику, даже если в логине есть datareader доступ ко всем таблицам на удаленном сервере.

Решение Microsoft состоит в том, чтобы предоставить учетным данным связанного сервера, выполняющему удаленный вызов, доступ SA, или ddladmin, или DBO к запрашиваемому удаленному серверу / таблицам.

Я использовал это, чтобы обойти эту проблему в некоторых наших установках, которая прозрачна для большей части решения без предоставления повышенных разрешений для БД или SQL-серверов на удаленной стороне. По сути, вам нужно предоставить роль удаленного входа в систему ddladmin для рассматриваемой удаленной базы данных SQL Server, а затем создать роль с явными разрешениями DENY для изменений уровня объекта, если вы только собираетесь разрешить доступ SELECT.

Ниже приведена копия пользовательской фиксированной роли БД, которую я создаю для этого, но вы можете протестировать и подтвердить или отрегулировать ее дополнительно, а также некоторые материалы для чтения и исследования, но в некоторых случаях они разрешаются прозрачно для меня - кэш может потребоваться очистить, хотя до того, как он заработает, имейте это в виду, и как только он будет очищен, запустите его дважды и проверьте результаты как локальной, так и удаленной активности.

Итак, разрешите учетные данные роли ddladmin на удаленной БД, разрешите другие обычные разрешения на удаленной БД, создайте пользовательскую роль БД, как я перечислил ниже на этом же сервере, а затем добавьте те же учетные данные в этот новый пользовательский фиксированный Роль БД с явным запретом, очистить кеш, выполнить запрос дважды или более после очистки кеша, чтобы посмотреть, разрешится ли он.

Чтобы конкретно ответить на ваш вопрос, хотя по той причине, что вы видите эти выборки курсора, если вы работаете с версией ниже SQL Server 2012 SP1 и видите это, и вы выполняете удаленный запрос, потому что он не разрешает использование или удаленный статистика в этой настройке без обходного пути (как указано выше), затем она выполняет построчную обработку, как указано выше Kin, так как запрос не оптимизирован с использованием статистики для лучшего плана запроса и имеет проблему с количеством элементов.

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

1

Ну ... мы решили проблему. В запущенной процедуре было обновление, которое "select * from ...". Я прокомментировал обновление. больше никаких проблем

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.