Infelizmente, o comportamento é bastante complexo e não documentado publicamente. Depende da declaração que está sendo executada, e alguns planos de execução usarão uma estratégia de aquisição / liberação de bloqueio que outros usarão outra. mas, como regra geral, os bloqueios S e IS são mantidos por um curto período de tempo e durante a execução da instrução, os bloqueios S podem ser adquiridos e liberados a uma taxa bastante frenética. Os bloqueios compartilhados são mantidos por muito tempo (durante a transação) somente nos níveis de isolamento de leitura repetível e leitura Searializable.
Sua melhor ferramenta para investigação é o Profiler, desde o Bloqueio: Adquirido e Bloqueio: Lançados os eventos são rastreados com todos os detalhes necessários. Os XEvents também podem ser usados, mas são um pouco mais complicados para fazê-los funcionar.
No entanto, se a contenção de bloqueio for um problema, uma solução trivial é ativar o isolamento de instantâneo de leitura confirmada. Quando isso é ativado, o Read Committed lê não mais adquirir qualquer bloqueio e obtém os dados bloqueados do armazenamento de versão no tempdb. A desvantagem é, obviamente, que o armazenamento de versão precisa ser mantido e ele adiciona a carga de trabalho ao tempdb.