En azından "Derlenmiş Planlar" açısından DMV size_in_bytes
alanının XML planındaki düğümün niteliğinden sys.dm_exec_cached_plans
daha büyük olmasının nedeni, Derlenmiş Planın Sorgu Planı ile aynı şey olmamasıdır. Derlenmiş Plan, birleştirilen boyutu alana eşit olan birden fazla Bellek Nesnesinden oluşur . Bu nedenle, belgelerde bulduğunuz " Önbellek nesnesi tarafından tüketilen bayt sayısı " açıklaması doğrudur; sadece DMV adı verildiğinde "önbellek nesnesi" ile ne kastedildiğini yanlış yorumlamak kolaydır ve "plan" terimi birden çok anlama sahiptir.CachedPlanSize
QueryPlan
size_in_bytes
Derlenmiş Plan, sorgu kümesiyle ilgili (örneğin yalnızca tek bir deyim değil) çeşitli bilgi parçalarını barındıran , bu parçalardan biri (veya daha fazlası) sorgu planlarıdır. Derlenmiş Planlar MEMOBJ_COMPILE_ADHOC üst düzey bir Bellek Nesnesi içerir ve bu satır , her iki DMV'deki alan sys.dm_os_memory_objects
aracılığıyla bağlanır memory_object_address
. Bu Bellek Nesnesi, sembol tablosu, parametre koleksiyonu, ilgili nesnelere bağlantılar, erişimci önbelleği, TDS meta veri önbelleği ve muhtemelen diğer bazı öğeleri içerir. Derleyen Planları Oturumlar / aynı yürütme Kullanıcılar arasında paylaşılır toplu aynı Oturum ayarlarla. Ancak, bazı ilgili nesneler vardır değil Oturumlar / Kullanıcılar arasında paylaştı.
Derlenmiş Planlar ayrıca plan_handle
( sys.dm_exec_cached_plans
içeri) sys.dm_exec_cached_plan_dependent_objects
DMF'ye geçirilerek bulunabilen bir veya daha fazla bağımlı nesneye sahiptir . İki tür bağımlı nesne vardır: Yürütülebilir Plan (Bellek Nesnesi = MEMOBJ_EXECUTE ) ve İmleç (Bellek Nesnesi = MEMOBJ_CURSOREXEC ). Her imleç için bir tane olmak üzere 0 veya daha fazla İmleç nesnesi olacaktır. Ayrıca bir ya da yürütülebilir Planı nesneleri daha, aynı yürütme her Kullanıcı başına bir olacaktır toplu dolayısıyla yürütülebilir Planları vardır, değilKullanıcılar arasında paylaşılır. Yürütülebilir Planlar, çalışma zamanı parametresini ve yerel değişken bilgilerini, şu anda yürütülen deyim gibi çalışma zamanı durumunu, çalışma zamanında oluşturulan nesneler için nesne kimliklerini içerir (bunun Tablo Değişkenleri, Geçici Tablolar, Geçici Saklı Yordamlar, vb. Anlamına geldiğini varsayıyorum) ve muhtemelen diğer öğeler.
Çok ifadeli bir toplu işteki her deyim Derlenmiş Bir Bildiride (Bellek Nesnesi = MEMOBJ_STATEMENT ) bulunur. Her Derlenmiş İfadenin (yani pages_in_bytes
) 1024'e bölünmüş boyutu , XML planındaki düğümlerin CachedPlanSize="xx"
değerleriyle eşleşmelidir <QueryPlan>
. Derlenmiş deyimler genellikle bir (muhtemelen daha fazla?) İlişkili çalışma zamanı sorgu planları (bellek nesnesi = MEMOBJ_XSTMT ) olacaktır. Son olarak, bir sorgu olan her çalışma zamanı Sorgu Planı için, ilişkili bir Sorgu Yürütme Bağlamı (Bellek Nesnesi = MEMOBJ_QUERYEXECCNTXTFORSE ) olmalıdır.
Derlenmiş Deyimler ile ilgili olarak, tek deyimli grupların ayrı Derlenmiş Deyimi (yani MEMOBJ_STATEMENT ) veya ayrı çalışma zamanı Sorgu Planı (yani MEMOBJ_XSTMT ) nesneleri yoktur. Bu nesnelerin her birinin değeri ana Derlenmiş Plan nesnesinde (yani MEMOBJ_COMPILE_ADHOC ) depolanır ve bu durumda, pages_in_bytes
bu ana nesnenin değerinin 1024'e bölünmesiyle XML planının düğümündeki CachedPlanSize
boyutla eşleşmelidir <QueryPlan>
. Bununla birlikte, bu değerler çok ifadeli gruplar halinde eşitlenmeyecektir.
Bu size_in_bytes
değer sys.dm_os_memory_objects
, tümü dm_os_memory_objects.page_allocator_address
bu Derlenmiş Plan için ilgili olan DMV'deki girişler (yukarıda kalın harflerle belirtilen öğeler) toplanarak elde edilebilir . Doğru bir değer elde etmek hüner ilk elde etmektir memory_object_address
gelen sys.dm_exec_cached_plans
belirli Derleyen Planı, daha sonra ilgili olsun kullanan MEMOBJ_COMPILE_ADHOC gelen satır sys.dm_os_memory_objects
onun dayalı memory_object_address
alana. Ardından, bu satırın page_allocator_address
değerini alın sys.dm_os_memory_objects
ve bu değeri sys.dm_os_memory_objects
aynı page_allocator_address
değere sahip tüm satırları almak için kullanın . (Bu tekniğin diğer Önbelleğe Alınmış Nesne türleri için çalışmadığını lütfen unutmayın: Ayrıştırma Ağacı , Genişletilmiş Proc , CLR Derlenmiş Proc ve CLR Derlenmiş Fon.)
Kullanılması memory_object_address
elde edilen değer sys.dm_exec_cached_plans
aşağıdaki sorguda aracılığıyla Derleyen Planı tüm bileşenlerini görebilirsiniz:
DECLARE @CompiledPlanAddress VARBINARY(8) = 0x00000001DC4A4060;
SELECT obj.memory_object_address, obj.pages_in_bytes, obj.type
FROM sys.dm_os_memory_objects obj
WHERE obj.page_allocator_address = (
SELECT planobj.page_allocator_address
FROM sys.dm_os_memory_objects planobj
WHERE planobj.memory_object_address = @CompiledPlanAddress
)
ORDER BY obj.[type], obj.pages_in_bytes;
Aşağıdaki sorgu sys.dm_exec_cached_plans
, Sorgu Planı ve her bir toplu iş için ifadeler ile birlikte tüm Derlenmiş Planları listeler . Doğrudan yukarıdaki sorgu, aşağıdaki sorguya XML aracılığıyla MemoryObjects
alan olarak dahil edilmiştir :
SELECT cplan.bucketid,
cplan.pool_id,
cplan.refcounts,
cplan.usecounts,
cplan.size_in_bytes,
cplan.memory_object_address,
cplan.cacheobjtype,
cplan.objtype,
cplan.plan_handle,
'---' AS [---],
qrypln.[query_plan],
sqltxt.[text],
'---' AS [---],
planobj.pages_in_bytes,
planobj.pages_in_bytes / 1024 AS [BaseSingleStatementPlanKB],
'===' AS [===],
cplan.size_in_bytes AS [TotalPlanBytes],
bytes.AllocatedBytes,
(SELECT CONVERT(VARCHAR(30), obj.memory_object_address, 1)
AS [memory_object_address], obj.pages_in_bytes, obj.[type]
--,obj.page_size_in_bytes
FROM sys.dm_os_memory_objects obj
WHERE obj.page_allocator_address = planobj.page_allocator_address
FOR XML RAW(N'object'), ROOT(N'memory_objects'), TYPE) AS [MemoryObjects]
FROM sys.dm_exec_cached_plans cplan
OUTER APPLY sys.dm_exec_sql_text(cplan.[plan_handle]) sqltxt
OUTER APPLY sys.dm_exec_query_plan(cplan.[plan_handle]) qrypln
INNER JOIN sys.dm_os_memory_objects planobj
ON planobj.memory_object_address = cplan.memory_object_address
OUTER APPLY (SELECT SUM(domo.[pages_in_bytes]) AS [AllocatedBytes]
FROM sys.dm_os_memory_objects domo
WHERE domo.page_allocator_address = planobj.page_allocator_address) bytes
WHERE cplan.parent_plan_handle IS NULL
AND cplan.cacheobjtype IN (N'Compiled Plan', N'Compiled Plan Stub')
--AND cplan.plan_handle = 0x06000D0031CD572910529CE001000000xxxxxxxx
ORDER BY cplan.objtype, cplan.plan_handle;
Lütfen bunu not al:
TotalPlanBytes
alan sadece bir yeniden ifadesidir sys.dm_exec_cached_plans.size_in_bytes
, bu alanda
AllocatedBytes
alanı genellikle eşleşen ilgili bellek nesneler toplamıdır TotalPlanBytes
(örneğin size_in_bytes
)
AllocatedBytes
Alan zaman daha büyük olacaktır TotalPlanBytes
(diğer bir deyişle size_in_bytes
) bağlı yürütme sırasında artan bellek tüketimi. Bu daha çok yeniden derleme nedeniyle ortaya çıkıyor gibi görünüyor (bu, usecounts
gösterilen alanla açıkça görülmelidir 1
)
BaseSingleStatementPlanKB
Alan gerektiğini eşleşecek CachedPlanSize
vasfını QueryPlan
XML düğümü, ancak sadece tek bir sorgu toplu kullanırken.
- birden çok sorgulu toplu işlerde, her sorgu için bir tane olmak
MEMOBJ_STATEMENT
üzere sys.dm_os_memory_objects
, içinde işaretlenmiş satırlar olmalıdır . pages_in_bytes
Bu satırlar için alan bireysel uyumlu olmalıdır <QueryPlan>
XML planının düğümleri.
Kaynaklar: