En azından "Derlenmiş Planlar" açısından DMV size_in_bytesalanının XML planındaki düğümün niteliğinden sys.dm_exec_cached_plansdaha 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.CachedPlanSizeQueryPlansize_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_objectsaracı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_plansiçeri) sys.dm_exec_cached_plan_dependent_objectsDMF'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_bytesbu ana nesnenin değerinin 1024'e bölünmesiyle XML planının düğümündeki CachedPlanSizeboyutla eşleşmelidir <QueryPlan>. Bununla birlikte, bu değerler çok ifadeli gruplar halinde eşitlenmeyecektir.
Bu size_in_bytesdeğer sys.dm_os_memory_objects, tümü dm_os_memory_objects.page_allocator_addressbu 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_addressgelen sys.dm_exec_cached_plansbelirli Derleyen Planı, daha sonra ilgili olsun kullanan MEMOBJ_COMPILE_ADHOC gelen satır sys.dm_os_memory_objectsonun dayalı memory_object_addressalana. Ardından, bu satırın page_allocator_addressdeğerini alın sys.dm_os_memory_objectsve bu değeri sys.dm_os_memory_objectsaynı page_allocator_addressdeğ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_addresselde edilen değer sys.dm_exec_cached_plansaş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 MemoryObjectsalan 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:
TotalPlanBytesalan sadece bir yeniden ifadesidir sys.dm_exec_cached_plans.size_in_bytes, bu alanda
AllocatedBytesalanı genellikle eşleşen ilgili bellek nesneler toplamıdır TotalPlanBytes(örneğin size_in_bytes)
AllocatedBytesAlan 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, usecountsgösterilen alanla açıkça görülmelidir 1)
BaseSingleStatementPlanKBAlan gerektiğini eşleşecek CachedPlanSizevasfını QueryPlanXML 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_bytesBu satırlar için alan bireysel uyumlu olmalıdır <QueryPlan>XML planının düğümleri.
Kaynaklar: