Ao executar uma consulta incluindo o plano de execução real, o operador raiz ( SELECT
) informa que o tamanho do plano em cache é 32 KB.
Uma consulta que une sys.dm_exec_cached_plans
e sys.dm_os_memory_objects
, examinando o plano em questão, diz que os valores para pages_in_bytes
e max_pages_in_bytes
são 32768 (32 KB), o que corresponde ao tamanho do plano armazenado em cache.
O que não entendo é o que significa o valor em sys.dm_exec_cached_plans.size_in_bytes
, que é 49152 (48 KB). Eu li BOL em todas essas colunas e, especialmente, size_in_bytes
que diz:
" Número de bytes consumidos pelo objeto de cache. "
Não consigo colocar a última peça do quebra-cabeça no lugar, para entender o que realmente significa.
Eu sei que todos os operadores (sem falar sobre a concessão de memória adicional usada para classificações e hashes) requerem alguma quantidade de memória fixa, para armazenar estado, fazer cálculos etc., que é armazenado com o plano otimizado no cache, mas onde?
Então, minhas perguntas são:
- O que
size_in_bytes
realmente significa - Por que é um valor maior do que "Tamanho do plano em cache"?
- Onde está reservada a quantidade fixa de memória para todos os operadores/iteradores, é com o "Tamanho do plano em cache" (32Kb no meu exemplo) ou em qualquer outro lugar?
Sei que são Detran diferentes com funções diferentes, mas estão relacionados. Os planos compilados (em cache) em sys.dm_exec_cached_plans
junções sys.dm_os_memory_objects
na memory_object_address
coluna. O motivo de postar as perguntas aqui, é que estou pedindo ajuda sobre isso, entendendo como interpretar os DMVs e suas colunas.
Se size_in_bytes
for o tamanho do plano em cache, por que o SQL Server informa outro valor no plano de execução real?
Nova consulta, novos números:
- Plano real
- Tamanho do plano em cache 16 KB
- CompileMemory 96KB
- Detran:
sys.dm_exec_cached_plans.size_in_bytes
24 KBsys.dm_os_memory_objects.pages_in_bytes, .max_pages_in_bytes
16 KB.
Além disso, observe que esta consulta não requer nenhuma concessão de memória adicional para classificações e operações de hash.
Microsoft SQL Server 2012 - 11.0.5343.0 (X64)
A razão pela qual o
size_in_bytes
campo dosys.dm_exec_cached_plans
DMV, pelo menos em termos de "Planos Compilados", é maior que oCachedPlanSize
atributo doQueryPlan
nó no plano XML é porque um Plano Compilado não é a mesma coisa que um Plano de Consulta. Um Plano Compilado é composto por vários Objetos de Memória, cujo tamanho combinado equivale aosize_in_bytes
campo. Portanto, a descrição de " Número de bytes consumidos pelo objeto de cache " que você encontrou na documentação é precisa; é apenas que é fácil interpretar mal o que significa "objeto de cache" dado o nome do DMV e que o termo "plano" tem vários significados.Um Plano Compilado é um contêiner que contém várias informações relacionadas ao lote de consulta (ou seja, não apenas uma única instrução), uma (ou mais) dessas partes sendo o(s) plano(s) de consulta. Os planos compilados têm um objeto de memória de nível superior de MEMOBJ_COMPILE_ADHOC, que é a linha
sys.dm_os_memory_objects
vinculada por meio domemory_object_address
campo em ambos os DMVs. Este objeto de memória contém a tabela de símbolos, coleção de parâmetros, links para objetos relacionados, cache do acessador, cache de metadados TDS e possivelmente alguns outros itens. Planos compilados são compartilhados entre Sessões/Usuários que estão executando o mesmo lote com as mesmas configurações de Sessão. No entanto, alguns objetos relacionados não são compartilhados entre sessões/usuários.Planos compilados também possuem um ou mais objetos dependentes que podem ser encontrados passando o
plan_handle
(insys.dm_exec_cached_plans
) para osys.dm_exec_cached_plan_dependent_objects
DMF. Existem dois tipos de objetos dependentes: Plano Executável (Objeto de Memória = MEMOBJ_EXECUTE ) e Cursor (Objeto de Memória = MEMOBJ_CURSOREXEC ). Haverá 0 ou mais objetos Cursor, um para cada cursor. Haverá também um ou mais objetos de Plano Executável, um para cada Usuário executando o mesmo lote , portanto Planos Executáveis não sãocompartilhada entre os usuários. Planos executáveis contêm parâmetros de tempo de execução e informações de variáveis locais, estado de tempo de execução, como a instrução atualmente em execução, IDs de objeto para objetos criados em tempo de execução (suponho que isso se refira a variáveis de tabela, tabelas temporárias, procedimentos armazenados temporários etc.) , e possivelmente outros itens.Cada instrução em um lote de várias instruções está contida em uma instrução compilada (objeto de memória = MEMOBJ_STATEMENT ). O tamanho de cada instrução compilada (ou seja,
pages_in_bytes
) dividido por 1024 deve corresponder aosCachedPlanSize="xx"
valores dos<QueryPlan>
nós no plano XML. As instruções compiladas geralmente têm um (possivelmente mais?) Planos de consulta de tempo de execução associados (objeto de memória = MEMOBJ_XSTMT ). Por fim, para cada plano de consulta em tempo de execução que seja uma consulta, deve haver um contexto de execução de consulta associado (objeto de memória = MEMOBJ_QUERYEXECCNTXTFORSE ).Com relação às instruções compiladas, os lotes de instrução única não têm objetos separados de instrução compilada (ou seja, MEMOBJ_STATEMENT ) ou plano de consulta de tempo de execução (ou seja, MEMOBJ_XSTMT ). O valor para cada um desses objetos será armazenado no objeto Plano Compilado principal (ou seja , MEMOBJ_COMPILE_ADHOC ) e, nesse caso, o
pages_in_bytes
valor desse objeto principal dividido por 1024 deve corresponder aoCachedPlanSize
tamanho no<QueryPlan>
nó do plano XML. Esses valores não serão iguais, no entanto, em lotes de várias instruções.O
size_in_bytes
valor pode ser derivado somando as entradas nosys.dm_os_memory_objects
DMV (os itens anotados acima em negrito), todos relacionadosdm_os_memory_objects.page_allocator_address
para esse Plano Compilado. O truque para obter o valor correto é primeiro obter omemory_object_address
fromsys.dm_exec_cached_plans
para um plano compilado específico e, em seguida, usá-lo para obter a linha MEMOBJ_COMPILE_ADHOCsys.dm_os_memory_objects
correspondente com base em seumemory_object_address
campo. Em seguida, pegue opage_allocator_address
valorsys.dm_os_memory_objects
dessa linha e use-o para pegar todas as linhassys.dm_os_memory_objects
que tenham o mesmopage_allocator_address
valor. (Observe que esta técnica não funciona para os outros tipos de objetos em cache: Parse Tree , Extended Proc , CLR Compiled Proc e CLR Compiled Func.)Usando o
memory_object_address
valor obtido desys.dm_exec_cached_plans
, você pode ver todos os componentes do Plano Compilado por meio da seguinte consulta:A consulta abaixo lista todos os Planos compilados
sys.dm_exec_cached_plans
junto com o Plano de consulta e as instruções para cada lote. A consulta diretamente acima é incorporada à consulta abaixo via XML como oMemoryObjects
campo:Observe que:
TotalPlanBytes
campo é apenas uma reafirmação dosys.dm_exec_cached_plans.size_in_bytes
campo,AllocatedBytes
campo é a SOMA dos objetos de memória relacionados que normalmente correspondemTotalPlanBytes
(ou sejasize_in_bytes
)AllocatedBytes
campo ocasionalmente será maior queTotalPlanBytes
(ou sejasize_in_bytes
, ) devido ao aumento do consumo de memória durante a execução. Isso parece acontecer principalmente devido à recompilação (que deve ser evidente com ousecounts
campo mostrando1
)BaseSingleStatementPlanKB
campo deve corresponder aoCachedPlanSize
atributo doQueryPlan
nó no XML, mas somente ao usar um único lote de consulta.MEMOBJ_STATEMENT
emsys.dm_os_memory_objects
, uma para cada consulta. Opages_in_bytes
campo dessas linhas deve corresponder aos<QueryPlan>
nós individuais do plano XML.Recursos:
O Pro SQL Server Internals examinou esse problema.