setup.sql 117 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140
  1. --
  2. -- © 2012 Microsoft. All Rights Reserved.
  3. --
  4. -- This script installs the stored procedures and functions invoked when a user opens the
  5. -- Performance Dashboard reports. This script must be run against each SQL Server instance which
  6. -- you plan to monitor via the reports.
  7. --
  8. -- Script must not be run in a transaction
  9. SET IMPLICIT_TRANSACTIONS OFF
  10. IF @@TRANCOUNT > 0 ROLLBACK TRAN
  11. GO
  12. -- Options that are saved with object definition
  13. SET QUOTED_IDENTIFIER ON -- Required to call methods on XML type
  14. SET ANSI_NULLS ON -- All queries use IS NULL check
  15. go
  16. use msdb
  17. go
  18. declare @Version nvarchar(100)
  19. declare @MajorVer tinyint
  20. declare @dec1 int
  21. select @Version = convert(nvarchar(100), serverproperty('ProductVersion'))
  22. select @dec1 = charindex('.', @Version)
  23. select @MajorVer = convert(tinyint, substring(@Version, 1, @dec1 - 1))
  24. if not (@MajorVer >= 10)
  25. begin
  26. RAISERROR('SETUP FAILED: This server does not meet the requirements (SQL 2008 or later) for running the Performance Dashboard Reports. This script will terminate and the required procedures will not be installed.', 18, 1)
  27. end
  28. GO
  29. -- Prevent installs against SQL Azure (cross DB query limitation and DMV scoping)
  30. if SERVERPROPERTY('Edition') = N'SQL Azure'
  31. begin
  32. RAISERROR('SETUP FAILED: SQL Azure is currently not supported by the Performance Dashboard Reports.', 18, 1);
  33. -- On SQL Azure we can't raise a high enough severity error to abort execution of the script, so this will
  34. -- unfortunately continue on past this point
  35. end
  36. go
  37. if not exists (select * from sys.schemas where name = 'MS_PerfDashboard')
  38. exec('create schema MS_PerfDashboard')
  39. go
  40. if OBJECTPROPERTY(object_id('MS_PerfDashboard.tblConfigValues'), 'IsUserTable') = 1
  41. drop table MS_PerfDashboard.tblConfigValues
  42. go
  43. create table MS_PerfDashboard.tblConfigValues
  44. (
  45. Attribute varchar(60) not null PRIMARY KEY,
  46. AttribValue sql_variant null
  47. )
  48. go
  49. set nocount on;
  50. go
  51. -- NOTE: ReportVersion attribute must be synchronized with .RDL version
  52. insert into MS_PerfDashboard.tblConfigValues (Attribute, AttribValue) values ('ReportVersion', '2012-01-31');
  53. insert into MS_PerfDashboard.tblConfigValues (Attribute, AttribValue) values ('InstalledDate', GETDATE());
  54. insert into MS_PerfDashboard.tblConfigValues (Attribute, AttribValue) values ('InstalledBy', SUSER_SNAME());
  55. go
  56. if object_id('MS_PerfDashboard.usp_CheckDependencies', 'P') is not null
  57. drop procedure MS_PerfDashboard.usp_CheckDependencies
  58. go
  59. create procedure MS_PerfDashboard.usp_CheckDependencies
  60. as
  61. begin
  62. declare @Version nvarchar(100)
  63. declare @MajorVer tinyint, @MinorVer tinyint, @BuildNum smallint
  64. declare @dec1 int, @dec2 int, @dec3 int
  65. select @Version = convert(nvarchar(100), serverproperty('ProductVersion'))
  66. select @dec1 = charindex('.', @Version)
  67. select @MajorVer = convert(tinyint, substring(@Version, 1, @dec1 - 1));
  68. select @MajorVer as major_version,
  69. NULL as minor_version,
  70. NULL as build_number,
  71. convert(nvarchar(128), SERVERPROPERTY('MachineName')) +
  72. CASE WHEN convert(nvarchar(128), SERVERPROPERTY('InstanceName')) IS NOT NULL THEN N'\' + convert(nvarchar(128), SERVERPROPERTY('InstanceName'))
  73. ELSE N''
  74. END as ServerInstance,
  75. @Version as ProductVersion,
  76. serverproperty('ProductLevel') as ProductLevel,
  77. serverproperty('Edition') as Edition
  78. if not (@MajorVer >= 10)
  79. begin
  80. RAISERROR('This server does not meet the requirements (SQL 2008 or later) for running the Performance Dashboard Reports. This server is running version %s', 18, 1, @Version)
  81. end
  82. end
  83. go
  84. grant execute on MS_PerfDashboard.usp_CheckDependencies to public
  85. go
  86. if OBJECTPROPERTY(object_id('MS_PerfDashboard.fn_WaitTypeCategory'), 'IsScalarFunction') = 1
  87. drop function MS_PerfDashboard.fn_WaitTypeCategory
  88. go
  89. create function MS_PerfDashboard.fn_WaitTypeCategory(@wait_type nvarchar(60))
  90. returns varchar(60)
  91. as
  92. begin
  93. declare @category nvarchar(60)
  94. select @category =
  95. case
  96. when @wait_type = N'SOS_SCHEDULER_YIELD' then N'CPU'
  97. when @wait_type = N'THREADPOOL' then N'Worker Thread'
  98. when @wait_type like N'LCK_M_%' then N'Lock'
  99. when @wait_type like N'LATCH_%' then N'Latch'
  100. when @wait_type like N'PAGELATCH_%' then N'Buffer Latch'
  101. when @wait_type like N'PAGEIOLATCH_%' then N'Buffer IO'
  102. when @wait_type like N'RESOURCE_SEMAPHORE_%' then N'Compilation'
  103. when @wait_type like N'CLR_%' or @wait_type like N'SQLCLR%' then N'SQL CLR'
  104. when @wait_type like N'DBMIRROR%' or @wait_type = N'MIRROR_SEND_MESSAGE' then N'Mirroring'
  105. when @wait_type like N'XACT%' or @wait_type like N'DTC_%' or @wait_type like N'TRAN_MARKLATCH_%' or @wait_type like N'MSQL_XACT_%' or @wait_type = N'TRANSACTION_MUTEX' then N'Transaction'
  106. when @wait_type like N'SLEEP_%' or @wait_type in(N'LAZYWRITER_SLEEP', N'SQLTRACE_BUFFER_FLUSH', N'SQLTRACE_INCREMENTAL_FLUSH_SLEEP', N'SQLTRACE_WAIT_ENTRIES', N'FT_IFTS_SCHEDULER_IDLE_WAIT', N'XE_DISPATCHER_WAIT', N'REQUEST_FOR_DEADLOCK_SEARCH', N'SLEEP_TASK', N'LOGMGR_QUEUE', N'ONDEMAND_TASK_QUEUE', N'CHECKPOINT_QUEUE', N'XE_TIMER_EVENT') then N'Idle'
  107. when @wait_type like N'PREEMPTIVE_%' then N'Preemptive'
  108. when @wait_type like N'BROKER_%' then N'Service Broker'
  109. when @wait_type in (N'LOGMGR', N'LOGBUFFER', N'LOGMGR_RESERVE_APPEND', N'LOGMGR_FLUSH', N'WRITELOG') then N'Tran Log IO'
  110. when @wait_type in (N'ASYNC_NETWORK_IO', N'NET_WAITFOR_PACKET') then N'Network IO'
  111. when @wait_type in (N'CXPACKET', N'EXCHANGE') then N'Parallelism'
  112. when @wait_type in (N'RESOURCE_SEMAPHORE', N'CMEMTHREAD', N'SOS_RESERVEDMEMBLOCKLIST') then N'Memory'
  113. when @wait_type in (N'WAITFOR', N'WAIT_FOR_RESULTS', N'BROKER_RECEIVE_WAITFOR') then N'User Wait'
  114. when @wait_type in (N'TRACEWRITE', N'SQLTRACE_LOCK', N'SQLTRACE_FILE_BUFFER', N'SQLTRACE_FILE_WRITE_IO_COMPLETION') then N'Tracing'
  115. when @wait_type in (N'FT_RESTART_CRAWL', N'FULLTEXT GATHERER', N'MSSEARCH') then N'Full Text Search'
  116. when @wait_type in (N'ASYNC_IO_COMPLETION', N'IO_COMPLETION', N'BACKUPIO', N'WRITE_COMPLETION') then N'Other Disk IO'
  117. else N'Other'
  118. end
  119. return @category
  120. end
  121. go
  122. GRANT EXECUTE ON MS_PerfDashboard.fn_WaitTypeCategory TO public
  123. go
  124. if OBJECTPROPERTY(object_id('MS_PerfDashboard.fn_QueryTextFromHandle'), 'IsTableFunction') = 1
  125. drop function MS_PerfDashboard.fn_QueryTextFromHandle
  126. go
  127. CREATE function MS_PerfDashboard.fn_QueryTextFromHandle(@handle varbinary(64), @statement_start_offset int, @statement_end_offset int)
  128. RETURNS @query_text TABLE (database_id smallint, object_id int, encrypted bit, query_text nvarchar(max))
  129. begin
  130. if @handle is not null
  131. begin
  132. declare @start int, @end int
  133. declare @dbid smallint, @objectid int, @encrypted bit
  134. declare @batch nvarchar(max), @query nvarchar(max)
  135. -- statement_end_offset is zero prior to beginning query execution (e.g., compilation)
  136. select
  137. @start = isnull(@statement_start_offset, 0),
  138. @end = case when @statement_end_offset is null or @statement_end_offset = 0 then -1
  139. else @statement_end_offset
  140. end
  141. select @dbid = t.dbid,
  142. @objectid = t.objectid,
  143. @encrypted = t.encrypted,
  144. @batch = t.text
  145. from sys.dm_exec_sql_text(@handle) as t
  146. select @query = case
  147. when @encrypted = cast(1 as bit) then N'encrypted text'
  148. else ltrim(substring(@batch, @start / 2 + 1, case when (@end - @start) / 2 >= 0 then (@end - @start) / 2 else 1000 end))
  149. end
  150. -- Found internal queries (e.g., CREATE INDEX) with end offset of original batch that is
  151. -- greater than the length of the internal query and thus returns nothing if we don't do this
  152. if datalength(@query) = 0
  153. begin
  154. select @query = @batch
  155. end
  156. insert into @query_text (database_id, object_id, encrypted, query_text)
  157. values (@dbid, @objectid, @encrypted, @query)
  158. end
  159. return
  160. end
  161. go
  162. GRANT SELECT ON MS_PerfDashboard.fn_QueryTextFromHandle TO public
  163. go
  164. if OBJECTPROPERTY(object_id('MS_PerfDashboard.fn_hexstrtovarbin'), 'IsScalarFunction') = 1
  165. drop function MS_PerfDashboard.fn_hexstrtovarbin
  166. go
  167. create function MS_PerfDashboard.fn_hexstrtovarbin(@input varchar(8000))
  168. returns varbinary(8000)
  169. as
  170. begin
  171. declare @result varbinary(8000)
  172. if @input is not null
  173. begin
  174. declare @i int, @l int
  175. select @result = 0x, @l = len(@input) / 2, @i = 2
  176. while @i <= @l
  177. begin
  178. set @result = @result +
  179. cast(cast(case lower(substring(@input, @i*2-1, 1))
  180. when '0' then 0x00
  181. when '1' then 0x10
  182. when '2' then 0x20
  183. when '3' then 0x30
  184. when '4' then 0x40
  185. when '5' then 0x50
  186. when '6' then 0x60
  187. when '7' then 0x70
  188. when '8' then 0x80
  189. when '9' then 0x90
  190. when 'a' then 0xa0
  191. when 'b' then 0xb0
  192. when 'c' then 0xc0
  193. when 'd' then 0xd0
  194. when 'e' then 0xe0
  195. when 'f' then 0xf0
  196. end as tinyint) |
  197. cast(case lower(substring(@input, @i*2, 1))
  198. when '0' then 0x00
  199. when '1' then 0x01
  200. when '2' then 0x02
  201. when '3' then 0x03
  202. when '4' then 0x04
  203. when '5' then 0x05
  204. when '6' then 0x06
  205. when '7' then 0x07
  206. when '8' then 0x08
  207. when '9' then 0x09
  208. when 'a' then 0x0a
  209. when 'b' then 0x0b
  210. when 'c' then 0x0c
  211. when 'd' then 0x0d
  212. when 'e' then 0x0e
  213. when 'f' then 0x0f
  214. end as tinyint) as binary(1))
  215. set @i = @i + 1
  216. end
  217. end
  218. return @result
  219. end
  220. go
  221. GRANT EXECUTE ON MS_PerfDashboard.fn_hexstrtovarbin TO public
  222. go
  223. if OBJECTPROPERTY(object_id('MS_PerfDashboard.fn_DatediffMilliseconds'), 'IsScalarFunction') = 1
  224. drop function MS_PerfDashboard.fn_DatediffMilliseconds
  225. go
  226. create function MS_PerfDashboard.fn_DatediffMilliseconds(@start datetime, @end datetime)
  227. returns bigint
  228. as
  229. begin
  230. return (datediff(dd, @start, @end) * cast(86400000 as bigint) + datediff(ms, dateadd(dd, datediff(dd, @start, @end), @start), @end))
  231. end
  232. go
  233. if object_id('MS_PerfDashboard.usp_Main_GetCPUHistory', 'P') is not null
  234. drop procedure MS_PerfDashboard.usp_Main_GetCPUHistory
  235. go
  236. create procedure MS_PerfDashboard.usp_Main_GetCPUHistory
  237. as
  238. begin
  239. declare @ms_now bigint
  240. select @ms_now = ms_ticks from sys.dm_os_sys_info;
  241. select top 15 record_id,
  242. dateadd(ms, -1 * (@ms_now - [timestamp]), GetDate()) as EventTime,
  243. SQLProcessUtilization,
  244. SystemIdle,
  245. 100 - SystemIdle - SQLProcessUtilization as OtherProcessUtilization
  246. from (
  247. select
  248. record.value('(./Record/@id)[1]', 'int') as record_id,
  249. record.value('(./Record/SchedulerMonitorEvent/SystemHealth/SystemIdle)[1]', 'int') as SystemIdle,
  250. record.value('(./Record/SchedulerMonitorEvent/SystemHealth/ProcessUtilization)[1]', 'int') as SQLProcessUtilization,
  251. timestamp
  252. from (
  253. select timestamp, convert(xml, record) as record
  254. from sys.dm_os_ring_buffers
  255. where ring_buffer_type = N'RING_BUFFER_SCHEDULER_MONITOR'
  256. and record like '%<SystemHealth>%') as x
  257. ) as y
  258. order by record_id desc
  259. end
  260. go
  261. grant execute on MS_PerfDashboard.usp_Main_GetCPUHistory to public
  262. go
  263. if object_id('MS_PerfDashboard.usp_Main_GetMiscInfo', 'P') is not null
  264. drop procedure MS_PerfDashboard.usp_Main_GetMiscInfo
  265. go
  266. create procedure MS_PerfDashboard.usp_Main_GetMiscInfo
  267. as
  268. begin
  269. select
  270. (select count(*) from sys.traces) as running_traces,
  271. (select count(*) from sys.databases) as number_of_databases,
  272. (select count(*) from sys.dm_db_missing_index_group_stats) as missing_index_count,
  273. (select waiting_tasks_count from sys.dm_os_wait_stats where wait_type = N'SQLCLR_QUANTUM_PUNISHMENT') as clr_quantum_waits,
  274. (select count(*) from sys.dm_os_ring_buffers where ring_buffer_type = N'RING_BUFFER_SCHEDULER_MONITOR' and record like N'%<NonYieldSchedBegin>%') as non_yield_count,
  275. (select cpu_count from sys.dm_os_sys_info) as number_of_cpus,
  276. (select scheduler_count from sys.dm_os_sys_info) as number_of_schedulers,
  277. (select COUNT(*) from sys.dm_xe_sessions) as number_of_xevent_sessions,
  278. (select convert(varchar(30), AttribValue) from MS_PerfDashboard.tblConfigValues where Attribute = 'ReportVersion') as report_script_version
  279. end
  280. go
  281. grant execute on MS_PerfDashboard.usp_Main_GetMiscInfo to public
  282. go
  283. if object_id('MS_PerfDashboard.usp_Main_GetSessionInfo', 'P') is not null
  284. drop procedure MS_PerfDashboard.usp_Main_GetSessionInfo
  285. go
  286. create procedure MS_PerfDashboard.usp_Main_GetSessionInfo
  287. as
  288. begin
  289. select count(*) as num_sessions,
  290. sum(convert(bigint, s.total_elapsed_time)) as total_elapsed_time,
  291. sum(convert(bigint, s.cpu_time)) as cpu_time,
  292. case when sum(convert(bigint, s.total_elapsed_time)) - sum(convert(bigint, s.cpu_time)) > 0
  293. then sum(convert(bigint, s.total_elapsed_time)) - sum(convert(bigint, s.cpu_time))
  294. else 0
  295. end as wait_time,
  296. sum(convert(bigint, MS_PerfDashboard.fn_DatediffMilliseconds(login_time, getdate()))) - sum(convert(bigint, s.total_elapsed_time)) as idle_connection_time,
  297. case when sum(s.logical_reads) > 0 then (sum(s.logical_reads) - isnull(sum(s.reads), 0)) / convert(float, sum(s.logical_reads))
  298. else NULL
  299. end as cache_hit_ratio
  300. from sys.dm_exec_sessions s
  301. where s.is_user_process = 0x1
  302. end
  303. go
  304. grant execute on MS_PerfDashboard.usp_Main_GetSessionInfo to public
  305. go
  306. if object_id('MS_PerfDashboard.usp_Main_GetRequestInfo', 'P') is not null
  307. drop procedure MS_PerfDashboard.usp_Main_GetRequestInfo
  308. go
  309. create procedure MS_PerfDashboard.usp_Main_GetRequestInfo
  310. as
  311. begin
  312. select count(r.request_id) as num_requests,
  313. sum(convert(bigint, r.total_elapsed_time)) as total_elapsed_time,
  314. sum(convert(bigint, r.cpu_time)) as cpu_time,
  315. case when sum(convert(bigint, r.total_elapsed_time)) - sum(convert(bigint, r.cpu_time)) > 0
  316. then sum(convert(bigint, r.total_elapsed_time)) - sum(convert(bigint, r.cpu_time))
  317. else 0
  318. end as wait_time,
  319. case when sum(r.logical_reads) > 0 then (sum(r.logical_reads) - isnull(sum(r.reads), 0)) / convert(float, sum(r.logical_reads))
  320. else NULL
  321. end as cache_hit_ratio
  322. from sys.dm_exec_requests r
  323. join sys.dm_exec_sessions s on r.session_id = s.session_id
  324. where s.is_user_process = 0x1
  325. end
  326. go
  327. grant execute on MS_PerfDashboard.usp_Main_GetRequestInfo to public
  328. go
  329. if object_id('MS_PerfDashboard.usp_Main_GetRequestWaits', 'P') is not null
  330. drop procedure MS_PerfDashboard.usp_Main_GetRequestWaits
  331. go
  332. create procedure MS_PerfDashboard.usp_Main_GetRequestWaits
  333. as
  334. begin
  335. SELECT
  336. r.session_id,
  337. MS_PerfDashboard.fn_WaitTypeCategory(r.wait_type) AS wait_category,
  338. r.wait_type,
  339. r.wait_time
  340. FROM sys.dm_exec_requests AS r
  341. INNER JOIN sys.dm_exec_sessions AS s ON r.session_id = s.session_id
  342. WHERE r.wait_type IS NOT NULL
  343. AND s.is_user_process = 0x1 -- TODO: parameterize
  344. end
  345. go
  346. GRANT EXECUTE ON MS_PerfDashboard.usp_Main_GetRequestWaits TO public
  347. go
  348. if object_id('MS_PerfDashboard.usp_GetPageDetails', 'P') is not null
  349. drop procedure MS_PerfDashboard.usp_GetPageDetails
  350. go
  351. create procedure MS_PerfDashboard.usp_GetPageDetails @wait_resource varchar(100)
  352. as
  353. begin
  354. declare @database_id smallint, @file_id smallint, @page_no int
  355. declare @t TABLE (ParentObject varchar(256), Object varchar(256), Field varchar(256), VALUE sql_variant)
  356. declare @colon1 int, @colon2 int
  357. select @colon1 = charindex(':', @wait_resource)
  358. select @colon2 = charindex(':', @wait_resource, @colon1 + 1)
  359. select @database_id = substring(@wait_resource, 1, @colon1 - 1)
  360. select @file_id = substring(@wait_resource, @colon1 + 1, @colon2 - @colon1 - 1)
  361. select @page_no = substring(@wait_resource, @colon2 + 1, 100)
  362. BEGIN TRY
  363. insert into @t exec sp_executesql N'dbcc page(@database_id, @file_id, @page_no) with tableresults', N'@database_id smallint, @file_id smallint, @page_no int', @database_id, @file_id, @page_no
  364. END TRY
  365. BEGIN CATCH
  366. --do nothing
  367. END CATCH
  368. select @database_id as database_id,
  369. quotename(db_name(@database_id)) as database_name,
  370. @file_id as file_id,
  371. @page_no as page_no,
  372. convert(int, [Metadata: ObjectId]) as [object_id],
  373. quotename(object_schema_name(convert(int, [Metadata: ObjectId]), @database_id)) + N'.' + quotename(object_name(convert(int, [Metadata: ObjectId]), @database_id)) as [object_name],
  374. convert(smallint, [Metadata: IndexId]) as [index_id],
  375. convert(int, [m_level]) as page_level,
  376. case convert(int, [m_type])
  377. when 1 then N'Data Page'
  378. when 2 then N'Index Page'
  379. when 3 then N'Text Mix Page'
  380. when 4 then N'Text Tree Page'
  381. when 8 then N'GAM Page'
  382. when 9 then N'SGAM Page'
  383. when 10 then N'IAM Page'
  384. when 11 then N'PFS Page'
  385. else convert(nvarchar(10), [m_type]) -- other types intentionally omitted
  386. end as page_type
  387. from (select * from @t where ParentObject = 'PAGE HEADER:' and
  388. Field IN ('Metadata: ObjectId', 'Metadata: IndexId', 'm_objId (AllocUnitId.idObj)', 'm_level', 'm_type')) as x
  389. pivot (min([VALUE]) for Field in ([Metadata: ObjectId], [Metadata: IndexId], [m_level], [m_type])) as z
  390. end
  391. go
  392. GRANT EXECUTE ON MS_PerfDashboard.usp_GetPageDetails TO public
  393. go
  394. if OBJECTPROPERTY(object_id('MS_PerfDashboard.usp_GetPlanGuideDetails'), 'IsProcedure') = 1
  395. drop procedure MS_PerfDashboard.usp_GetPlanGuideDetails
  396. go
  397. create procedure MS_PerfDashboard.usp_GetPlanGuideDetails @database_name nvarchar(128), @plan_guide_name nvarchar(128)
  398. as
  399. begin
  400. if (LEFT(@database_name, 1) = N'[' and RIGHT(@database_name, 1) = N']')
  401. begin
  402. select @database_name = substring(@database_name, 2, len(@database_name) - 2)
  403. end
  404. if (LEFT(@plan_guide_name, 1) = N'[' and RIGHT(@plan_guide_name, 1) = N']')
  405. begin
  406. select @plan_guide_name = substring(@plan_guide_name, 2, len(@plan_guide_name) - 2)
  407. end
  408. if db_id(@database_name) is not null
  409. begin
  410. declare @cmd nvarchar(4000)
  411. select @cmd = N'select * from [' + @database_name + N'].[sys].[plan_guides] where name = @P1'
  412. exec sp_executesql @cmd, N'@P1 nvarchar(128)', @plan_guide_name
  413. end
  414. else
  415. begin
  416. -- return empty result set
  417. select * from [sys].[plan_guides] where 0 = 1
  418. end
  419. end
  420. go
  421. grant execute on MS_PerfDashboard.usp_GetPlanGuideDetails to public
  422. go
  423. if OBJECTPROPERTY(object_id('MS_PerfDashboard.usp_TransformShowplanXMLToTable'), 'IsProcedure') = 1
  424. drop procedure MS_PerfDashboard.usp_TransformShowplanXMLToTable
  425. go
  426. CREATE PROCEDURE MS_PerfDashboard.usp_TransformShowplanXMLToTable @plan_handle nvarchar(256), @stmt_start_offset int, @stmt_end_offset int, @fDebug bit = 0x0
  427. AS
  428. BEGIN
  429. SET NOCOUNT ON
  430. declare @plan nvarchar(max)
  431. declare @dbid int, @objid int
  432. declare @xml_plan xml
  433. declare @error int
  434. declare @output TABLE (
  435. node_id int,
  436. parent_node_id int,
  437. relevant_xml_text nvarchar(max),
  438. stmt_text nvarchar(max),
  439. logical_op nvarchar(128),
  440. physical_op nvarchar(128),
  441. output_list nvarchar(max),
  442. avg_row_size float,
  443. est_cpu float,
  444. est_io float,
  445. est_rows float,
  446. est_rewinds float,
  447. est_rebinds float,
  448. est_subtree_cost float,
  449. warnings nvarchar(max))
  450. BEGIN TRY
  451. -- handle may be invalid now, or XML may be too deep to convert
  452. select @dbid = p.dbid, @objid = p.objectid, @plan = p.query_plan from sys.dm_exec_text_query_plan(msdb.MS_PerfDashboard.fn_hexstrtovarbin(@plan_handle), @stmt_start_offset, @stmt_end_offset) as p
  453. select @xml_plan = convert(xml, @plan)
  454. ;WITH XMLNAMESPACES ('http://schemas.microsoft.com/sqlserver/2004/07/showplan' AS sp)
  455. insert into @output
  456. select nd.node_id,
  457. x.parent_node_id,
  458. case when @fDebug = 0x1 then
  459. case
  460. when x.parent_node_id is null then @plan
  461. else convert(nvarchar(max), x.plan_node)
  462. end
  463. else NULL
  464. end as relevant_xml_text,
  465. nd.stmt_text,
  466. nd.logical_op,
  467. nd.physical_op,
  468. nd.output_list,
  469. nd.avg_row_size,
  470. nd.est_cpu,
  471. nd.est_io,
  472. nd.est_rows,
  473. nd.est_rewinds,
  474. nd.est_rebinds,
  475. nd.est_subtree_cost,
  476. nd.warnings
  477. from (select
  478. splan.row.query('.') as plan_node,
  479. splan.row.value('../../@NodeId', 'int') as parent_node_id
  480. from (select @xml_plan as query_plan) as p
  481. cross apply p.query_plan.nodes('//sp:RelOp') as splan (row)) as x
  482. outer apply MS_PerfDashboard.fn_ShowplanRowDetails(plan_node) as nd
  483. order by isnull(parent_node_id, -1) asc
  484. -- Statements such as WAITFOR, etc may not have a RelOp so just show the statement type if available
  485. if @@rowcount = 0
  486. begin
  487. ;WITH XMLNAMESPACES ('http://schemas.microsoft.com/sqlserver/2004/07/showplan' AS sp)
  488. insert into @output (stmt_text) select isnull(@xml_plan.value('(//@StatementType)[1]', 'nvarchar(max)'), N'Unknown Statement')
  489. end
  490. END TRY
  491. BEGIN CATCH
  492. select @error = ERROR_NUMBER()
  493. -- select
  494. -- cast(NULL as int) as node_id,
  495. -- cast(NULL as int) as parent_node_id,
  496. -- cast(NULL as nvarchar(max)) as relevant_xml_text,
  497. -- cast(NULL as nvarchar(max)) as stmt_text,
  498. -- cast(NULL as nvarchar(128)) as logical_op,
  499. -- cast(NULL as nvarchar(128)) as physical_op,
  500. -- cast(NULL as nvarchar(max)) as output_list,
  501. -- cast(NULL as float) as avg_row_size,
  502. -- cast(NULL as float) as est_cpu,
  503. -- cast(NULL as float) as est_io,
  504. -- cast(NULL as float) as est_rows,
  505. -- cast(NULL as float) as est_rewinds,
  506. -- cast(NULL as float) as est_rebinds,
  507. -- cast(NULL as float) as est_subtree_cost,
  508. -- cast(NULL as nvarchar(max)) as warnings
  509. -- where 0 = 1
  510. END CATCH
  511. -- This may be an empty set if there was an exception caught above
  512. SELECT
  513. node_id,
  514. parent_node_id,
  515. relevant_xml_text,
  516. stmt_text,
  517. logical_op,
  518. physical_op,
  519. output_list,
  520. avg_row_size,
  521. est_cpu,
  522. est_io,
  523. est_rows,
  524. est_rewinds,
  525. est_rebinds,
  526. est_subtree_cost,
  527. warnings
  528. FROM @output
  529. END
  530. go
  531. grant execute on MS_PerfDashboard.usp_TransformShowplanXMLToTable to public
  532. go
  533. /*
  534. *
  535. * Helper procedures for building showplan output. These are called, indirectly, by MS_PerfDashboard.usp_TransformShowplanXMLToTable and because
  536. * they belong to the same schema we do not need to grant EXECUTE permissions to users. They are not intended to be called directly as they require
  537. * proper context within the showplan XML in order to return meaningful output.
  538. *
  539. *
  540. */
  541. if OBJECTPROPERTY(object_id('MS_PerfDashboard.fn_ShowplanBuildColumnReference'), 'IsScalarFunction') = 1
  542. drop function MS_PerfDashboard.fn_ShowplanBuildColumnReference
  543. go
  544. create function MS_PerfDashboard.fn_ShowplanBuildColumnReference(@node_data xml, @include_alias_or_table bit)
  545. returns nvarchar(max)
  546. as
  547. begin
  548. declare @output nvarchar(max)
  549. declare @table nvarchar(256), @alias nvarchar(256), @column nvarchar(256)
  550. ;WITH XMLNAMESPACES ('http://schemas.microsoft.com/sqlserver/2004/07/showplan' AS sp)
  551. select @alias = @node_data.value('(./sp:ColumnReference/@Alias)[1]', 'nvarchar(256)'),
  552. @table = @node_data.value('(./sp:ColumnReference/@Table)[1]', 'nvarchar(256)'),
  553. @column = @node_data.value('(./sp:ColumnReference/@Column)[1]', 'nvarchar(256)')
  554. select @column = case when left(@column, 1) = N'[' and right(@column, 1) = N']' then @column else quotename(@column) end
  555. if @include_alias_or_table = 0x1 and coalesce(@alias, @table) is not null
  556. begin
  557. select @alias = case when left(@alias, 1) = N'[' and right(@alias, 1) = N']' then @alias else quotename(@alias) end
  558. select @table = case when left(@table, 1) = N'[' and right(@table, 1) = N']' then @table else quotename(@table) end
  559. select @output = case
  560. when @alias is not null then @alias
  561. else @table
  562. end + N'.' + @column
  563. end
  564. else
  565. begin
  566. select @output = @column
  567. end
  568. return @output
  569. end
  570. go
  571. if OBJECTPROPERTY(object_id('MS_PerfDashboard.fn_ShowplanBuildColumnReferenceList'), 'IsScalarFunction') = 1
  572. drop function MS_PerfDashboard.fn_ShowplanBuildColumnReferenceList
  573. go
  574. create function MS_PerfDashboard.fn_ShowplanBuildColumnReferenceList (@node_data xml, @include_alias_or_table bit)
  575. returns nvarchar(max)
  576. as
  577. begin
  578. declare @output nvarchar(max)
  579. declare @count int, @ctr int
  580. ;WITH XMLNAMESPACES ('http://schemas.microsoft.com/sqlserver/2004/07/showplan' AS sp)
  581. select @output = N'', @ctr = 1, @count = @node_data.value('count(./sp:ColumnReference)', 'int')
  582. -- iterate over each element in the list
  583. while @ctr <= @count
  584. begin
  585. ;WITH XMLNAMESPACES ('http://schemas.microsoft.com/sqlserver/2004/07/showplan' AS sp)
  586. select @output = @output + case when @ctr > 1 then N', ' else N'' end + MS_PerfDashboard.fn_ShowplanBuildColumnReference(@node_data.query('./sp:ColumnReference[position() = sql:variable("@ctr")]'), @include_alias_or_table)
  587. select @ctr = @ctr + 1
  588. end
  589. return @output
  590. end
  591. go
  592. if OBJECTPROPERTY(object_id('MS_PerfDashboard.fn_ShowplanBuildDefinedValuesList'), 'IsScalarFunction') = 1
  593. drop function MS_PerfDashboard.fn_ShowplanBuildDefinedValuesList
  594. go
  595. create function MS_PerfDashboard.fn_ShowplanBuildDefinedValuesList (@node_data xml)
  596. returns nvarchar(max)
  597. as
  598. begin
  599. declare @output nvarchar(max)
  600. ;WITH XMLNAMESPACES ('http://schemas.microsoft.com/sqlserver/2004/07/showplan' AS sp)
  601. select @output = convert(nvarchar(max), @node_data.query('for $val in /sp:DefinedValue
  602. return concat(($val/sp:ColumnReference/@Column)[1], "=", ($val/sp:ScalarOperator/@ScalarString)[1], ",")'))
  603. declare @len int
  604. select @len = len(@output)
  605. if (@len > 0)
  606. begin
  607. select @output = left(@output, @len - 1)
  608. end
  609. return @output
  610. end
  611. go
  612. if OBJECTPROPERTY(object_id('MS_PerfDashboard.fn_ShowplanBuildOrderBy'), 'IsScalarFunction') = 1
  613. drop function MS_PerfDashboard.fn_ShowplanBuildOrderBy
  614. go
  615. create function MS_PerfDashboard.fn_ShowplanBuildOrderBy (@node_data xml)
  616. returns nvarchar(max)
  617. as
  618. begin
  619. declare @output nvarchar(max)
  620. ;WITH XMLNAMESPACES ('http://schemas.microsoft.com/sqlserver/2004/07/showplan' AS sp)
  621. select @output = convert(nvarchar(max), @node_data.query('for $col in /sp:OrderByColumn
  622. return concat(if (($col/sp:ColumnReference/@Alias)[1] > "") then concat(($col/sp:ColumnReference/@Alias)[1], ".") else if (($col/sp:ColumnReference/@Table)[1] > "") then concat(($col/sp:ColumnReference/@Table)[1], ".") else "", string(($col/sp:ColumnReference/@Column)[1]), if ($col/@Ascending = 1) then " ASC" else " DESC", ",")'))
  623. declare @len int
  624. select @len = len(@output)
  625. if (@len > 0)
  626. begin
  627. select @output = left(@output, @len - 1)
  628. end
  629. return @output
  630. end
  631. go
  632. if OBJECTPROPERTY(object_id('MS_PerfDashboard.fn_ShowplanBuildRowset'), 'IsScalarFunction') = 1
  633. drop function MS_PerfDashboard.fn_ShowplanBuildRowset
  634. go
  635. create function MS_PerfDashboard.fn_ShowplanBuildRowset (@node_data xml)
  636. returns nvarchar(max)
  637. as
  638. begin
  639. declare @output nvarchar(max)
  640. ;WITH XMLNAMESPACES ('http://schemas.microsoft.com/sqlserver/2004/07/showplan' AS sp)
  641. select @output = MS_PerfDashboard.fn_ShowplanBuildObject(@node_data.query('./sp:Object'))
  642. return @output
  643. end
  644. go
  645. if OBJECTPROPERTY(object_id('MS_PerfDashboard.fn_ShowplanBuildScalarExpression'), 'IsScalarFunction') = 1
  646. drop function MS_PerfDashboard.fn_ShowplanBuildScalarExpression
  647. go
  648. create function MS_PerfDashboard.fn_ShowplanBuildScalarExpression (@node_data xml)
  649. returns nvarchar(max)
  650. as
  651. begin
  652. declare @output nvarchar(max)
  653. select @output = N''
  654. ;WITH XMLNAMESPACES ('http://schemas.microsoft.com/sqlserver/2004/07/showplan' AS sp)
  655. select @output = @node_data.value('(./sp:ScalarOperator/@ScalarString)[1]', 'nvarchar(max)')
  656. return @output
  657. end
  658. go
  659. if OBJECTPROPERTY(object_id('MS_PerfDashboard.fn_ShowplanBuildScalarExpressionList'), 'IsScalarFunction') = 1
  660. drop function MS_PerfDashboard.fn_ShowplanBuildScalarExpressionList
  661. go
  662. create function MS_PerfDashboard.fn_ShowplanBuildScalarExpressionList (@node_data xml)
  663. returns nvarchar(max)
  664. as
  665. begin
  666. declare @output nvarchar(max)
  667. ;WITH XMLNAMESPACES ('http://schemas.microsoft.com/sqlserver/2004/07/showplan' AS sp)
  668. select @output = convert(nvarchar(max), @node_data.query('for $op in ./sp:ScalarOperator
  669. return concat(string($op/@ScalarString), ",")'))
  670. declare @len int
  671. select @len = len(@output)
  672. if (@len > 0)
  673. begin
  674. select @output = left(@output, @len - 1)
  675. end
  676. return @output
  677. end
  678. go
  679. if OBJECTPROPERTY(object_id('MS_PerfDashboard.fn_ShowplanBuildScanRange'), 'IsScalarFunction') = 1
  680. drop function MS_PerfDashboard.fn_ShowplanBuildScanRange
  681. go
  682. create function MS_PerfDashboard.fn_ShowplanBuildScanRange (@node_data xml, @scan_type nvarchar(30))
  683. returns nvarchar(max)
  684. as
  685. begin
  686. declare @output nvarchar(max)
  687. set @output = N''
  688. declare @count int, @ctr int
  689. if (@node_data.exist('declare namespace sp="http://schemas.microsoft.com/sqlserver/2004/07/showplan"; ./sp:RangeColumns') = 1)
  690. begin
  691. ;WITH XMLNAMESPACES ('http://schemas.microsoft.com/sqlserver/2004/07/showplan' AS sp)
  692. select @ctr = 1, @count = @node_data.value('count(./sp:RangeColumns/sp:ColumnReference)', 'int')
  693. while @ctr <= @count
  694. begin
  695. ;WITH XMLNAMESPACES ('http://schemas.microsoft.com/sqlserver/2004/07/showplan' AS sp)
  696. select @output = @output +
  697. case when @ctr > 1 then N' AND ' else '' end + MS_PerfDashboard.fn_ShowplanBuildColumnReferenceList(@node_data.query('./sp:RangeColumns/sp:ColumnReference[position() = sql:variable("@ctr")]'), 0x1)
  698. + N' ' +
  699. case UPPER(@scan_type)
  700. when 'BINARY IS' then N'IS'
  701. when 'EQ' then N'='
  702. when 'GE' then N'>='
  703. when 'GT' then N'>'
  704. when 'IS' then N'IS'
  705. when 'IS NOT' then N'IS NOT'
  706. when 'IS NOT NULL' then N'IS NOT NULL'
  707. when 'IS NULL' then N'IS NULL'
  708. when 'LE' then N'<='
  709. when 'LT' then N'<'
  710. when 'NE' then N'<>'
  711. end
  712. + N' '
  713. + MS_PerfDashboard.fn_ShowplanBuildScalarExpressionList(@node_data.query('./sp:RangeExpressions/sp:ScalarOperator[position() = sql:variable("@ctr")]'))
  714. select @ctr = @ctr + 1
  715. end
  716. end
  717. --if (@node_data.exist('declare namespace sp="http://schemas.microsoft.com/sqlserver/2004/07/showplan"; ./sp:RangeExpressions') = 1)
  718. --begin
  719. -- ;WITH XMLNAMESPACES ('http://schemas.microsoft.com/sqlserver/2004/07/showplan' AS sp)
  720. -- select @output = @output + N'(RANGE: (' + MS_PerfDashboard.fn_ShowplanBuildScalarExpressionList(@node_data.query('./sp:RangeExpressions/*')) + N'))'
  721. --end
  722. return @output
  723. end
  724. go
  725. if OBJECTPROPERTY(object_id('MS_PerfDashboard.fn_ShowplanBuildSeekPredicates'), 'IsScalarFunction') = 1
  726. drop function MS_PerfDashboard.fn_ShowplanBuildSeekPredicates
  727. go
  728. create function MS_PerfDashboard.fn_ShowplanBuildSeekPredicates (@node_data xml)
  729. returns nvarchar(max)
  730. as
  731. begin
  732. declare @output nvarchar(max)
  733. declare @count int, @ctr int
  734. ;WITH XMLNAMESPACES ('http://schemas.microsoft.com/sqlserver/2004/07/showplan' AS sp)
  735. select @output = N'', @ctr = 1, @count = @node_data.value('count(./sp:SeekPredicates/sp:SeekPredicate)', 'int')
  736. -- iterate over each element in the list
  737. while @ctr <= @count
  738. begin
  739. ;WITH XMLNAMESPACES ('http://schemas.microsoft.com/sqlserver/2004/07/showplan' AS sp)
  740. select @output = @output + case when @ctr > 1 then N' AND ' else N'' end + MS_PerfDashboard.fn_ShowplanBuildSeekPredicate(@node_data.query('./sp:SeekPredicates/sp:SeekPredicate[position() = sql:variable("@ctr")]/*'))
  741. select @ctr = @ctr + 1
  742. end
  743. return @output;
  744. end
  745. go
  746. if OBJECTPROPERTY(object_id('MS_PerfDashboard.fn_ShowplanBuildSeekPredicatesNew'), 'IsScalarFunction') = 1
  747. drop function MS_PerfDashboard.fn_ShowplanBuildSeekPredicatesNew
  748. go
  749. CREATE function [MS_PerfDashboard].[fn_ShowplanBuildSeekPredicatesNew] (@node_data xml)
  750. returns nvarchar(max)
  751. as
  752. begin
  753. declare @output nvarchar(max)
  754. declare @count int, @ctr int
  755. ;WITH XMLNAMESPACES ('http://schemas.microsoft.com/sqlserver/2004/07/showplan' AS sp)
  756. select @output = N'', @ctr = 1, @count = @node_data.value('count(./sp:SeekPredicates/sp:SeekPredicateNew)', 'int')
  757. -- iterate over each element in the list
  758. while @ctr <= @count
  759. begin
  760. ;WITH XMLNAMESPACES ('http://schemas.microsoft.com/sqlserver/2004/07/showplan' AS sp)
  761. select @output = @output + case when @ctr > 1 then N' AND ' else N'' end + MS_PerfDashboard.fn_ShowplanBuildSeekPredicate(@node_data.query('./sp:SeekPredicates/sp:SeekPredicateNew/sp:SeekKeys[position() = sql:variable("@ctr")]/*'))
  762. select @ctr = @ctr + 1
  763. end
  764. return @output
  765. end
  766. go
  767. if OBJECTPROPERTY(object_id('MS_PerfDashboard.fn_ShowplanBuildSeekPredicate'), 'IsScalarFunction') = 1
  768. drop function MS_PerfDashboard.fn_ShowplanBuildSeekPredicate
  769. go
  770. create function MS_PerfDashboard.fn_ShowplanBuildSeekPredicate (@node_data xml)
  771. returns nvarchar(max)
  772. as
  773. begin
  774. declare @output nvarchar(max)
  775. set @output = N''
  776. if (@node_data.exist('declare namespace sp="http://schemas.microsoft.com/sqlserver/2004/07/showplan"; ./sp:IsNotNull') = 1)
  777. begin
  778. ;WITH XMLNAMESPACES ('http://schemas.microsoft.com/sqlserver/2004/07/showplan' AS sp)
  779. select @output = @output + MS_PerfDashboard.fn_ShowplanBuildColumnReference(@node_data.query('./sp:IsNotNull/sp:ColumnReference'), 0x0) + N' IS NOT NULL'
  780. end
  781. if (@node_data.exist('declare namespace sp="http://schemas.microsoft.com/sqlserver/2004/07/showplan"; ./sp:Prefix') = 1)
  782. begin
  783. ;WITH XMLNAMESPACES ('http://schemas.microsoft.com/sqlserver/2004/07/showplan' AS sp)
  784. select @output = @output + MS_PerfDashboard.fn_ShowplanBuildScanRange(@node_data.query('./sp:Prefix/*'), @node_data.value('(./sp:Prefix/@ScanType)[1]', 'nvarchar(100)'))
  785. end
  786. if (@node_data.exist('declare namespace sp="http://schemas.microsoft.com/sqlserver/2004/07/showplan"; ./sp:StartRange') = 1)
  787. begin
  788. ;WITH XMLNAMESPACES ('http://schemas.microsoft.com/sqlserver/2004/07/showplan' AS sp)
  789. select @output = @output + case when datalength(@output) > 0 then N' AND ' else '' end + MS_PerfDashboard.fn_ShowplanBuildScanRange(@node_data.query('./sp:StartRange/*'), @node_data.value('(./sp:StartRange/@ScanType)[1]', 'nvarchar(100)'))
  790. end
  791. if (@node_data.exist('declare namespace sp="http://schemas.microsoft.com/sqlserver/2004/07/showplan"; ./sp:EndRange') = 1)
  792. begin
  793. ;WITH XMLNAMESPACES ('http://schemas.microsoft.com/sqlserver/2004/07/showplan' AS sp)
  794. select @output = @output + case when datalength(@output) > 0 then N' AND ' else '' end + MS_PerfDashboard.fn_ShowplanBuildScanRange(@node_data.query('./sp:EndRange/*'), @node_data.value('(./sp:EndRange/@ScanType)[1]', 'nvarchar(100)'))
  795. end
  796. return @output
  797. end
  798. go
  799. if OBJECTPROPERTY(object_id('MS_PerfDashboard.fn_ShowplanBuildObject'), 'IsScalarFunction') = 1
  800. drop function MS_PerfDashboard.fn_ShowplanBuildObject
  801. go
  802. create function MS_PerfDashboard.fn_ShowplanBuildObject (@node_data xml)
  803. returns nvarchar(max)
  804. as
  805. begin
  806. declare @object nvarchar(max)
  807. set @object = N''
  808. if (@node_data.exist('declare namespace sp="http://schemas.microsoft.com/sqlserver/2004/07/showplan"; ./sp:Object/@Server') = 1)
  809. begin
  810. ;WITH XMLNAMESPACES ('http://schemas.microsoft.com/sqlserver/2004/07/showplan' AS sp)
  811. select @object = @object + @node_data.value('(./sp:Object/@Server)[1]', 'nvarchar(128)') + N'.'
  812. end
  813. if (@node_data.exist('declare namespace sp="http://schemas.microsoft.com/sqlserver/2004/07/showplan"; ./sp:Object/@Database') = 1)
  814. begin
  815. ;WITH XMLNAMESPACES ('http://schemas.microsoft.com/sqlserver/2004/07/showplan' AS sp)
  816. select @object = @object + @node_data.value('(./sp:Object/@Database)[1]', 'nvarchar(128)') + N'.'
  817. end
  818. if (@node_data.exist('declare namespace sp="http://schemas.microsoft.com/sqlserver/2004/07/showplan"; ./sp:Object/@Schema') = 1)
  819. begin
  820. ;WITH XMLNAMESPACES ('http://schemas.microsoft.com/sqlserver/2004/07/showplan' AS sp)
  821. select @object = @object + @node_data.value('(./sp:Object/@Schema)[1]', 'nvarchar(128)') + N'.'
  822. end
  823. if (@node_data.exist('declare namespace sp="http://schemas.microsoft.com/sqlserver/2004/07/showplan"; ./sp:Object/@Table') = 1)
  824. begin
  825. ;WITH XMLNAMESPACES ('http://schemas.microsoft.com/sqlserver/2004/07/showplan' AS sp)
  826. select @object = @object + @node_data.value('(./sp:Object/@Table)[1]', 'nvarchar(128)')
  827. end
  828. if (@node_data.exist('declare namespace sp="http://schemas.microsoft.com/sqlserver/2004/07/showplan"; ./sp:Object/@Index') = 1)
  829. begin
  830. ;WITH XMLNAMESPACES ('http://schemas.microsoft.com/sqlserver/2004/07/showplan' AS sp)
  831. select @object = @object + N'.' + @node_data.value('(./sp:Object/@Index)[1]', 'nvarchar(128)')
  832. end
  833. if (@node_data.exist('declare namespace sp="http://schemas.microsoft.com/sqlserver/2004/07/showplan"; ./sp:Object/@Alias') = 1)
  834. begin
  835. ;WITH XMLNAMESPACES ('http://schemas.microsoft.com/sqlserver/2004/07/showplan' AS sp)
  836. select @object = @object + N' AS ' + @node_data.value('(./sp:Object/@Alias)[1]', 'nvarchar(128)')
  837. end
  838. return @object
  839. end
  840. go
  841. if OBJECTPROPERTY(object_id('MS_PerfDashboard.fn_ShowplanBuildWarnings'), 'IsScalarFunction') = 1
  842. drop function MS_PerfDashboard.fn_ShowplanBuildWarnings
  843. go
  844. create function MS_PerfDashboard.fn_ShowplanBuildWarnings(@relop_node xml)
  845. returns nvarchar(max)
  846. as
  847. begin
  848. declare @output nvarchar(max)
  849. if (@relop_node.exist('declare namespace sp="http://schemas.microsoft.com/sqlserver/2004/07/showplan"; ./sp:RelOp/sp:Warnings') = 1)
  850. begin
  851. if (@relop_node.exist('declare namespace sp="http://schemas.microsoft.com/sqlserver/2004/07/showplan"; ./sp:RelOp/sp:Warnings[@NoJoinPredicate = 1]') = 1)
  852. begin
  853. select @output = N'NO JOIN PREDICATE'
  854. end
  855. if (@relop_node.exist('declare namespace sp="http://schemas.microsoft.com/sqlserver/2004/07/showplan"; ./sp:RelOp/sp:Warnings/sp:ColumnsWithNoStatistics') = 1)
  856. begin
  857. ;with xmlnamespaces ('http://schemas.microsoft.com/sqlserver/2004/07/showplan' as sp)
  858. select @output = case when @output is null then N'' else @output + N', ' end + N'NO STATS: ' + MS_PerfDashboard.fn_ShowplanBuildColumnReferenceList(@relop_node.query('./sp:RelOp/sp:Warnings/sp:ColumnsWithNoStatistics/*'), 0x1)
  859. end
  860. end
  861. return @output
  862. end
  863. go
  864. if OBJECTPROPERTY(object_id('MS_PerfDashboard.fn_ShowplanFormatAssert'), 'IsScalarFunction') = 1
  865. drop function MS_PerfDashboard.fn_ShowplanFormatAssert
  866. go
  867. CREATE FUNCTION MS_PerfDashboard.fn_ShowplanFormatAssert(@node_data xml)
  868. RETURNS nvarchar(max)
  869. as
  870. begin
  871. declare @output nvarchar(max)
  872. ;WITH XMLNAMESPACES ('http://schemas.microsoft.com/sqlserver/2004/07/showplan' AS sp)
  873. select @output = N'Assert(' + @node_data.value('(./sp:Assert/sp:Predicate/sp:ScalarOperator/@ScalarString)[1]', 'nvarchar(max)') + N'))'
  874. return @output;
  875. end
  876. go
  877. if OBJECTPROPERTY(object_id('MS_PerfDashboard.fn_ShowplanFormatBitmap'), 'IsScalarFunction') = 1
  878. drop function MS_PerfDashboard.fn_ShowplanFormatBitmap
  879. go
  880. CREATE FUNCTION MS_PerfDashboard.fn_ShowplanFormatBitmap(@node_data xml)
  881. RETURNS nvarchar(max)
  882. as
  883. begin
  884. declare @output nvarchar(max)
  885. ;WITH XMLNAMESPACES ('http://schemas.microsoft.com/sqlserver/2004/07/showplan' AS sp)
  886. select @output = N'Bitmap(Hash Keys:(' + MS_PerfDashboard.fn_ShowplanBuildColumnReferenceList(@node_data.query('./sp:Bitmap/sp:HashKeys/sp:ColumnReference'), 0x1) + N'))'
  887. return @output;
  888. end
  889. go
  890. if OBJECTPROPERTY(object_id('MS_PerfDashboard.fn_ShowplanFormatComputeScalar'), 'IsScalarFunction') = 1
  891. drop function MS_PerfDashboard.fn_ShowplanFormatComputeScalar
  892. go
  893. CREATE FUNCTION MS_PerfDashboard.fn_ShowplanFormatComputeScalar(@node_data xml, @physical_op nvarchar(128))
  894. returns nvarchar(max)
  895. as
  896. begin
  897. declare @output nvarchar(max)
  898. ;WITH XMLNAMESPACES ('http://schemas.microsoft.com/sqlserver/2004/07/showplan' AS sp)
  899. select @output = @physical_op + N'(DEFINE: (' + MS_PerfDashboard.fn_ShowplanBuildDefinedValuesList(@node_data.query('./sp:DefinedValues/*')) + N'))';
  900. return @output;
  901. end
  902. go
  903. if OBJECTPROPERTY(object_id('MS_PerfDashboard.fn_ShowplanFormatConcat'), 'IsScalarFunction') = 1
  904. drop function MS_PerfDashboard.fn_ShowplanFormatConcat
  905. go
  906. CREATE FUNCTION MS_PerfDashboard.fn_ShowplanFormatConcat(@node_data xml)
  907. RETURNS nvarchar(max)
  908. as
  909. begin
  910. return N'Concatenation'
  911. end
  912. go
  913. if OBJECTPROPERTY(object_id('MS_PerfDashboard.fn_ShowplanFormatCollapse'), 'IsScalarFunction') = 1
  914. drop function MS_PerfDashboard.fn_ShowplanFormatCollapse
  915. go
  916. CREATE FUNCTION MS_PerfDashboard.fn_ShowplanFormatCollapse(@node_data xml)
  917. RETURNS nvarchar(max)
  918. as
  919. begin
  920. return N'Collapse'
  921. end
  922. go
  923. if OBJECTPROPERTY(object_id('MS_PerfDashboard.fn_ShowplanFormatIndexScan'), 'IsScalarFunction') = 1
  924. drop function MS_PerfDashboard.fn_ShowplanFormatIndexScan
  925. go
  926. CREATE FUNCTION MS_PerfDashboard.fn_ShowplanFormatIndexScan(@node_data xml, @physical_op nvarchar(128))
  927. RETURNS nvarchar(max)
  928. as
  929. begin
  930. declare @output nvarchar(max)
  931. ;WITH XMLNAMESPACES ('http://schemas.microsoft.com/sqlserver/2004/07/showplan' AS sp)
  932. select @output = @physical_op + N'(OBJECT: (' + MS_PerfDashboard.fn_ShowplanBuildObject(@node_data.query('./sp:IndexScan/sp:Object')) + N')'
  933. if (@node_data.exist('declare namespace sp="http://schemas.microsoft.com/sqlserver/2004/07/showplan"; ./sp:IndexScan/sp:SeekPredicates/sp:SeekPredicate') = 1)
  934. begin
  935. ;WITH XMLNAMESPACES ('http://schemas.microsoft.com/sqlserver/2004/07/showplan' AS sp)
  936. select @output = @output + N', SEEK: (' + MS_PerfDashboard.fn_ShowplanBuildSeekPredicates(@node_data.query('./sp:IndexScan/sp:SeekPredicates')) + N')'
  937. end
  938. else if (@node_data.exist('declare namespace sp="http://schemas.microsoft.com/sqlserver/2004/07/showplan"; ./sp:IndexScan/sp:SeekPredicates/sp:SeekPredicateNew') = 1)
  939. begin
  940. ;WITH XMLNAMESPACES ('http://schemas.microsoft.com/sqlserver/2004/07/showplan' AS sp)
  941. select @output = @output + N', SEEK: (' + MS_PerfDashboard.fn_ShowplanBuildSeekPredicatesNew(@node_data.query('./sp:IndexScan/sp:SeekPredicates')) + N')'
  942. end
  943. if (@node_data.exist('declare namespace sp="http://schemas.microsoft.com/sqlserver/2004/07/showplan"; ./sp:IndexScan/sp:Predicate') = 1)
  944. begin
  945. ;WITH XMLNAMESPACES ('http://schemas.microsoft.com/sqlserver/2004/07/showplan' AS sp)
  946. select @output = @output + N', WHERE: (' + MS_PerfDashboard.fn_ShowplanBuildScalarExpression(@node_data.query('./sp:IndexScan/sp:Predicate/*')) + N')'
  947. end
  948. select @output = @output + N')'
  949. if (@node_data.exist('declare namespace sp="http://schemas.microsoft.com/sqlserver/2004/07/showplan"; ./sp:IndexScan[@Lookup = 1]') = 1)
  950. begin
  951. select @output = @output + N' LOOKUP'
  952. end
  953. if (@node_data.exist('declare namespace sp="http://schemas.microsoft.com/sqlserver/2004/07/showplan"; ./sp:IndexScan[@Ordered = 1]') = 1)
  954. begin
  955. ;WITH XMLNAMESPACES ('http://schemas.microsoft.com/sqlserver/2004/07/showplan' AS sp)
  956. select @output = @output + N' ORDERED ' + ISNULL(@node_data.value('(./sp:IndexScan/@ScanDirection)[1]', 'nvarchar(128)'), '')
  957. end
  958. if (@node_data.exist('declare namespace sp="http://schemas.microsoft.com/sqlserver/2004/07/showplan"; ./sp:IndexScan[@ForcedIndex = 1]') = 1)
  959. begin
  960. select @output = @output + N' FORCEDINDEX'
  961. end
  962. return @output;
  963. end
  964. go
  965. if OBJECTPROPERTY(object_id('MS_PerfDashboard.fn_ShowplanFormatConstantScan'), 'IsScalarFunction') = 1
  966. drop function MS_PerfDashboard.fn_ShowplanFormatConstantScan
  967. go
  968. CREATE FUNCTION MS_PerfDashboard.fn_ShowplanFormatConstantScan(@node_data xml)
  969. RETURNS nvarchar(max)
  970. as
  971. begin
  972. declare @output nvarchar(max)
  973. select @output = N'Constant Scan'
  974. if (@node_data.exist('declare namespace sp="http://schemas.microsoft.com/sqlserver/2004/07/showplan"; ./sp:ConstantScan/sp:Values') = 1)
  975. begin
  976. ;WITH XMLNAMESPACES ('http://schemas.microsoft.com/sqlserver/2004/07/showplan' AS sp)
  977. select @output = @output + N'(VALUES: (' + MS_PerfDashboard.fn_ShowplanBuildScalarExpressionList(@node_data.query('./sp:ConstantScan/sp:Values/sp:Row/*')) + N'))'
  978. end
  979. return @output
  980. end
  981. go
  982. if OBJECTPROPERTY(object_id('MS_PerfDashboard.fn_ShowplanFormatDeletedInsertedScan'), 'IsScalarFunction') = 1
  983. drop function MS_PerfDashboard.fn_ShowplanFormatDeletedInsertedScan
  984. go
  985. -- Passed the Rowset element of XML showplan and extracts the Object details
  986. CREATE FUNCTION MS_PerfDashboard.fn_ShowplanFormatDeletedInsertedScan(@node_data xml, @physical_op nvarchar(128))
  987. RETURNS nvarchar(max)
  988. as
  989. begin
  990. declare @output nvarchar(max)
  991. ;WITH XMLNAMESPACES ('http://schemas.microsoft.com/sqlserver/2004/07/showplan' AS sp)
  992. select @output = @physical_op + N'(' + MS_PerfDashboard.fn_ShowplanBuildRowset(@node_data) + N')'
  993. return @output;
  994. end
  995. go
  996. if OBJECTPROPERTY(object_id('MS_PerfDashboard.fn_ShowplanFormatFilter'), 'IsScalarFunction') = 1
  997. drop function MS_PerfDashboard.fn_ShowplanFormatFilter
  998. go
  999. CREATE FUNCTION MS_PerfDashboard.fn_ShowplanFormatFilter(@node_data xml)
  1000. RETURNS nvarchar(max)
  1001. as
  1002. begin
  1003. declare @output nvarchar(max)
  1004. declare @fStartup tinyint
  1005. ;WITH XMLNAMESPACES ('http://schemas.microsoft.com/sqlserver/2004/07/showplan' AS sp)
  1006. select @fStartup = case when (@node_data.exist('./sp:Filter[@StartupExpression = 1]') = 1) then 1 else 0 end
  1007. ;WITH XMLNAMESPACES ('http://schemas.microsoft.com/sqlserver/2004/07/showplan' AS sp)
  1008. select @output = N'Filter(WHERE: (' +
  1009. case when @fStartup = 1 then N'STARTUP EXPRESSION(' else N'' end +
  1010. MS_PerfDashboard.fn_ShowplanBuildScalarExpression(@node_data.query('./sp:Filter/sp:Predicate/*')) +
  1011. case when @fStartup = 1 then N')' else N'' end +
  1012. N'))'
  1013. return @output;
  1014. end
  1015. go
  1016. if OBJECTPROPERTY(object_id('MS_PerfDashboard.fn_ShowplanFormatHashMatch'), 'IsScalarFunction') = 1
  1017. drop function MS_PerfDashboard.fn_ShowplanFormatHashMatch
  1018. go
  1019. CREATE FUNCTION MS_PerfDashboard.fn_ShowplanFormatHashMatch(@node_data xml, @logical_op nvarchar(128))
  1020. RETURNS nvarchar(max)
  1021. as
  1022. begin
  1023. declare @output nvarchar(max)
  1024. select @output = N'Hash Match(' + @logical_op
  1025. if (@logical_op = N'Aggregate')
  1026. begin
  1027. if (@node_data.exist('declare namespace sp="http://schemas.microsoft.com/sqlserver/2004/07/showplan"; ./sp:Hash/sp:HashKeysBuild') = 1)
  1028. begin
  1029. ;WITH XMLNAMESPACES ('http://schemas.microsoft.com/sqlserver/2004/07/showplan' AS sp)
  1030. select @output = @output + N', HASH:(' + MS_PerfDashboard.fn_ShowplanBuildColumnReferenceList(@node_data.query('./sp:Hash/sp:HashKeysBuild/sp:ColumnReference'), 0x1) + N')'
  1031. end
  1032. if (@node_data.exist('declare namespace sp="http://schemas.microsoft.com/sqlserver/2004/07/showplan"; ./sp:Hash/sp:BuildResidual') = 1)
  1033. begin
  1034. ;WITH XMLNAMESPACES ('http://schemas.microsoft.com/sqlserver/2004/07/showplan' AS sp)
  1035. select @output = @output + N', RESIDUAL:(' + MS_PerfDashboard.fn_ShowplanBuildScalarExpression(@node_data.query('./sp:Hash/sp:BuildResidual/*')) + N')'
  1036. end
  1037. ;WITH XMLNAMESPACES ('http://schemas.microsoft.com/sqlserver/2004/07/showplan' AS sp)
  1038. select @output = @output + N', DEFINE: (' + MS_PerfDashboard.fn_ShowplanBuildDefinedValuesList(@node_data.query('./sp:Hash/sp:DefinedValues/*')) + N')';
  1039. end
  1040. else
  1041. begin
  1042. if (@node_data.exist('declare namespace sp="http://schemas.microsoft.com/sqlserver/2004/07/showplan"; ./sp:Hash/sp:HashKeysBuild') = 1)
  1043. begin
  1044. ;WITH XMLNAMESPACES ('http://schemas.microsoft.com/sqlserver/2004/07/showplan' AS sp)
  1045. select @output = @output + N', HASH:(' +
  1046. MS_PerfDashboard.fn_ShowplanBuildColumnReferenceList(@node_data.query('./sp:Hash/sp:HashKeysBuild/sp:ColumnReference'), 0x1) +
  1047. N')=(' +
  1048. MS_PerfDashboard.fn_ShowplanBuildColumnReferenceList(@node_data.query('./sp:Hash/sp:HashKeysProbe/sp:ColumnReference'), 0x1) + N')'
  1049. end
  1050. if (@node_data.exist('declare namespace sp="http://schemas.microsoft.com/sqlserver/2004/07/showplan"; ./sp:Hash/sp:BuildResidual') = 1) or
  1051. (@node_data.exist('declare namespace sp="http://schemas.microsoft.com/sqlserver/2004/07/showplan"; ./sp:Hash/sp:ProbeResidual') = 1)
  1052. begin
  1053. declare @build_residual bit
  1054. select @build_residual = 0x0, @output = @output + N', RESIDUAL:('
  1055. if (@node_data.exist('declare namespace sp="http://schemas.microsoft.com/sqlserver/2004/07/showplan"; ./sp:Hash/sp:BuildResidual') = 1)
  1056. begin
  1057. ;WITH XMLNAMESPACES ('http://schemas.microsoft.com/sqlserver/2004/07/showplan' AS sp)
  1058. select @output = @output + MS_PerfDashboard.fn_ShowplanBuildScalarExpression(@node_data.query('./sp:Hash/sp:BuildResidual/*'))
  1059. select @build_residual = 0x1
  1060. end
  1061. if (@node_data.exist('declare namespace sp="http://schemas.microsoft.com/sqlserver/2004/07/showplan"; ./sp:Hash/sp:ProbeResidual') = 1)
  1062. begin
  1063. ;WITH XMLNAMESPACES ('http://schemas.microsoft.com/sqlserver/2004/07/showplan' AS sp)
  1064. select @output = @output + case when @build_residual = 0x1 then N' AND ' else '' end + MS_PerfDashboard.fn_ShowplanBuildScalarExpression(@node_data.query('./sp:Hash/sp:ProbeResidual/*'))
  1065. end
  1066. select @output = @output + N')'
  1067. end
  1068. end
  1069. select @output = @output + N')'
  1070. return @output;
  1071. end
  1072. go
  1073. if OBJECTPROPERTY(object_id('MS_PerfDashboard.fn_ShowplanFormatMerge'), 'IsScalarFunction') = 1
  1074. drop function MS_PerfDashboard.fn_ShowplanFormatMerge
  1075. go
  1076. CREATE FUNCTION MS_PerfDashboard.fn_ShowplanFormatMerge(@node_data xml, @logical_op nvarchar(128))
  1077. RETURNS nvarchar(max)
  1078. as
  1079. begin
  1080. declare @output nvarchar(max)
  1081. ;WITH XMLNAMESPACES ('http://schemas.microsoft.com/sqlserver/2004/07/showplan' AS sp)
  1082. select @output = N'Merge Join(' + @logical_op + case when @node_data.exist('./sp:Merge[@ManyToMany = 1]') = 1 then N', MANY-TO-MANY'
  1083. else N'' end
  1084. if (@node_data.exist('declare namespace sp="http://schemas.microsoft.com/sqlserver/2004/07/showplan"; ./sp:Merge/sp:InnerSideJoinColumns') = 1)
  1085. begin
  1086. ;WITH XMLNAMESPACES ('http://schemas.microsoft.com/sqlserver/2004/07/showplan' AS sp)
  1087. select @output = @output + N', MERGE: (' + MS_PerfDashboard.fn_ShowplanBuildColumnReferenceList(@node_data.query('./sp:Merge/sp:InnerSideJoinColumns/sp:ColumnReference'), 0x1) + N')=(' + MS_PerfDashboard.fn_ShowplanBuildColumnReferenceList(@node_data.query('./sp:Merge/sp:OuterSideJoinColumns/sp:ColumnReference'), 0x1) + N')'
  1088. end
  1089. if (@node_data.exist('declare namespace sp="http://schemas.microsoft.com/sqlserver/2004/07/showplan"; ./sp:Merge/sp:Residual') = 1)
  1090. begin
  1091. ;WITH XMLNAMESPACES ('http://schemas.microsoft.com/sqlserver/2004/07/showplan' AS sp)
  1092. select @output = @output + N', RESIDUAL: (' + MS_PerfDashboard.fn_ShowplanBuildScalarExpression(@node_data.query('./sp:Merge/sp:Residual/*')) + N')'
  1093. end
  1094. if (@node_data.exist('declare namespace sp="http://schemas.microsoft.com/sqlserver/2004/07/showplan"; ./sp:Merge/sp:PassThru') = 1)
  1095. begin
  1096. ;WITH XMLNAMESPACES ('http://schemas.microsoft.com/sqlserver/2004/07/showplan' AS sp)
  1097. select @output = @output + N', PASSTHRU: (' + MS_PerfDashboard.fn_ShowplanBuildScalarExpression(@node_data.query('./sp:Merge/sp:PassThru/*')) + N')'
  1098. end
  1099. select @output = @output + N')'
  1100. return @output;
  1101. end
  1102. go
  1103. if OBJECTPROPERTY(object_id('MS_PerfDashboard.fn_ShowplanFormatNestedLoops'), 'IsScalarFunction') = 1
  1104. drop function MS_PerfDashboard.fn_ShowplanFormatNestedLoops
  1105. go
  1106. CREATE FUNCTION MS_PerfDashboard.fn_ShowplanFormatNestedLoops(@node_data xml, @logical_op nvarchar(128))
  1107. RETURNS nvarchar(max)
  1108. as
  1109. begin
  1110. declare @output nvarchar(max)
  1111. select @output = N'Nested Loops(' + @logical_op
  1112. if (@node_data.exist('declare namespace sp="http://schemas.microsoft.com/sqlserver/2004/07/showplan"; ./sp:NestedLoops/sp:OuterReferences') = 1)
  1113. begin
  1114. ;WITH XMLNAMESPACES ('http://schemas.microsoft.com/sqlserver/2004/07/showplan' AS sp)
  1115. select @output = @output + N', OUTER REFERENCES:' + MS_PerfDashboard.fn_ShowplanBuildColumnReferenceList(@node_data.query('./sp:NestedLoops/sp:OuterReferences/sp:ColumnReference'), 0x1)
  1116. end
  1117. if (@node_data.exist('declare namespace sp="http://schemas.microsoft.com/sqlserver/2004/07/showplan"; ./sp:NestedLoops/sp:Predicate') = 1)
  1118. begin
  1119. ;WITH XMLNAMESPACES ('http://schemas.microsoft.com/sqlserver/2004/07/showplan' AS sp)
  1120. select @output = @output + N', WHERE: (' + MS_PerfDashboard.fn_ShowplanBuildScalarExpression(@node_data.query('./sp:NestedLoops/sp:Predicate/*')) + N')'
  1121. end
  1122. if (@node_data.exist('declare namespace sp="http://schemas.microsoft.com/sqlserver/2004/07/showplan"; ./sp:NestedLoops/sp:PassThru') = 1)
  1123. begin
  1124. ;WITH XMLNAMESPACES ('http://schemas.microsoft.com/sqlserver/2004/07/showplan' AS sp)
  1125. select @output = @output + N', PASSTHRU:(' + MS_PerfDashboard.fn_ShowplanBuildScalarExpression(@node_data.query('./sp:NestedLoops/sp:PassThru/*')) + N')'
  1126. end
  1127. select @output = @output + N')'
  1128. if (@node_data.exist('declare namespace sp="http://schemas.microsoft.com/sqlserver/2004/07/showplan"; ./sp:NestedLoops[@Optimized = 1]') = 1)
  1129. begin
  1130. select @output = @output + N' OPTIMIZED'
  1131. end
  1132. if (@node_data.exist('declare namespace sp="http://schemas.microsoft.com/sqlserver/2004/07/showplan"; ./sp:NestedLoops[@WithOrderedPrefetch = 1]') = 1)
  1133. begin
  1134. select @output = @output + N' WITH ORDERED PREFETCH'
  1135. end
  1136. else if (@node_data.exist('declare namespace sp="http://schemas.microsoft.com/sqlserver/2004/07/showplan"; ./sp:NestedLoops[@WithUnorderedPrefetch = 1]') = 1)
  1137. begin
  1138. select @output = @output + N' WITH UNORDERED PREFETCH'
  1139. end
  1140. return @output;
  1141. end
  1142. go
  1143. if OBJECTPROPERTY(object_id('MS_PerfDashboard.fn_ShowplanFormatParallelism'), 'IsScalarFunction') = 1
  1144. drop function MS_PerfDashboard.fn_ShowplanFormatParallelism
  1145. go
  1146. CREATE FUNCTION MS_PerfDashboard.fn_ShowplanFormatParallelism(@node_data xml, @logical_op nvarchar(128))
  1147. RETURNS nvarchar(max)
  1148. as
  1149. begin
  1150. declare @output nvarchar(max)
  1151. select @output = N'Parallelism(' + @logical_op + N')'
  1152. --TODO: Extend to show partitioning information, order by information
  1153. return @output;
  1154. end
  1155. go
  1156. if OBJECTPROPERTY(object_id('MS_PerfDashboard.fn_ShowplanFormatSimpleUpdate'), 'IsScalarFunction') = 1
  1157. drop function MS_PerfDashboard.fn_ShowplanFormatSimpleUpdate
  1158. go
  1159. CREATE FUNCTION MS_PerfDashboard.fn_ShowplanFormatSimpleUpdate(@node_data xml, @physical_op nvarchar(128))
  1160. RETURNS nvarchar(max)
  1161. as
  1162. begin
  1163. declare @output nvarchar(max)
  1164. ;WITH XMLNAMESPACES ('http://schemas.microsoft.com/sqlserver/2004/07/showplan' AS sp)
  1165. select @output = @physical_op + N'(' + MS_PerfDashboard.fn_ShowplanBuildObject(@node_data.query('./sp:Object'))
  1166. if (@node_data.exist('declare namespace sp="http://schemas.microsoft.com/sqlserver/2004/07/showplan"; ./sp:SetPredicate') = 1)
  1167. begin
  1168. ;WITH XMLNAMESPACES ('http://schemas.microsoft.com/sqlserver/2004/07/showplan' AS sp)
  1169. select @output = @output + N', SET: ' + MS_PerfDashboard.fn_ShowplanBuildScalarExpression(@node_data.query('./sp:SetPredicate/*'))
  1170. end
  1171. if (@node_data.exist('declare namespace sp="http://schemas.microsoft.com/sqlserver/2004/07/showplan"; ./sp:SeekPredicate') = 1)
  1172. begin
  1173. ;WITH XMLNAMESPACES ('http://schemas.microsoft.com/sqlserver/2004/07/showplan' AS sp)
  1174. select @output = @output + N', WHERE: (' + MS_PerfDashboard.fn_ShowplanBuildSeekPredicate(@node_data.query('./sp:SeekPredicate/*')) + N')'
  1175. end
  1176. select @output = @output + N')'
  1177. return @output;
  1178. end
  1179. go
  1180. if OBJECTPROPERTY(object_id('MS_PerfDashboard.fn_ShowplanFormatRemoteQuery'), 'IsScalarFunction') = 1
  1181. drop function MS_PerfDashboard.fn_ShowplanFormatRemoteQuery
  1182. go
  1183. CREATE FUNCTION MS_PerfDashboard.fn_ShowplanFormatRemoteQuery(@node_data xml)
  1184. RETURNS nvarchar(max)
  1185. as
  1186. begin
  1187. declare @output nvarchar(max)
  1188. select @output = N'Remote Query('
  1189. if (@node_data.exist('declare namespace sp="http://schemas.microsoft.com/sqlserver/2004/07/showplan"; ./sp:RemoteQuery/@RemoteSource') = 1)
  1190. begin
  1191. ;WITH XMLNAMESPACES ('http://schemas.microsoft.com/sqlserver/2004/07/showplan' AS sp)
  1192. select @output = @output + N'SOURCE: (' + @node_data.value('(./sp:RemoteQuery/@RemoteSource)[1]', 'nvarchar(256)') + N')'
  1193. end
  1194. if (@node_data.exist('declare namespace sp="http://schemas.microsoft.com/sqlserver/2004/07/showplan"; ./sp:RemoteQuery/@RemoteObject') = 1)
  1195. begin
  1196. ;WITH XMLNAMESPACES ('http://schemas.microsoft.com/sqlserver/2004/07/showplan' AS sp)
  1197. select @output = @output + N'OBJECT: (' + @node_data.value('(./sp:RemoteQuery/@RemoteObject)[1]', 'nvarchar(256)') + N')'
  1198. end
  1199. if (@node_data.exist('declare namespace sp="http://schemas.microsoft.com/sqlserver/2004/07/showplan"; ./sp:RemoteQuery/@RemoteQuery') = 1)
  1200. begin
  1201. ;WITH XMLNAMESPACES ('http://schemas.microsoft.com/sqlserver/2004/07/showplan' AS sp)
  1202. select @output = @output + N', QUERY: (' + @node_data.value('(./sp:RemoteQuery/@RemoteQuery)[1]', 'nvarchar(max)') + N')'
  1203. end
  1204. select @output = @output + N')'
  1205. return @output;
  1206. end
  1207. go
  1208. if OBJECTPROPERTY(object_id('MS_PerfDashboard.fn_ShowplanFormatRemoteScan'), 'IsScalarFunction') = 1
  1209. drop function MS_PerfDashboard.fn_ShowplanFormatRemoteScan
  1210. go
  1211. CREATE FUNCTION MS_PerfDashboard.fn_ShowplanFormatRemoteScan(@node_data xml)
  1212. RETURNS nvarchar(max)
  1213. as
  1214. begin
  1215. declare @output nvarchar(max)
  1216. select @output = N'Remote Scan('
  1217. if (@node_data.exist('declare namespace sp="http://schemas.microsoft.com/sqlserver/2004/07/showplan"; ./sp:RemoteScan/@RemoteSource') = 1)
  1218. begin
  1219. ;WITH XMLNAMESPACES ('http://schemas.microsoft.com/sqlserver/2004/07/showplan' AS sp)
  1220. select @output = @output + N'SOURCE: (' + @node_data.value('(./sp:RemoteScan/@RemoteSource)[1]', 'nvarchar(256)') + N')'
  1221. end
  1222. if (@node_data.exist('declare namespace sp="http://schemas.microsoft.com/sqlserver/2004/07/showplan"; ./sp:RemoteScan/@RemoteObject') = 1)
  1223. begin
  1224. ;WITH XMLNAMESPACES ('http://schemas.microsoft.com/sqlserver/2004/07/showplan' AS sp)
  1225. select @output = @output + N'OBJECT: (' + @node_data.value('(./sp:RemoteScan/@RemoteObject)[1]', 'nvarchar(256)') + N')'
  1226. end
  1227. select @output = @output + N')'
  1228. return @output;
  1229. end
  1230. go
  1231. if OBJECTPROPERTY(object_id('MS_PerfDashboard.fn_ShowplanFormatRemoteModify'), 'IsScalarFunction') = 1
  1232. drop function MS_PerfDashboard.fn_ShowplanFormatRemoteModify
  1233. go
  1234. CREATE FUNCTION MS_PerfDashboard.fn_ShowplanFormatRemoteModify(@node_data xml, @logical_op nvarchar(128))
  1235. RETURNS nvarchar(max)
  1236. as
  1237. begin
  1238. declare @output nvarchar(max)
  1239. select @output = @logical_op + N'('
  1240. if (@node_data.exist('declare namespace sp="http://schemas.microsoft.com/sqlserver/2004/07/showplan"; ./sp:RemoteModify/@RemoteSource') = 1)
  1241. begin
  1242. ;WITH XMLNAMESPACES ('http://schemas.microsoft.com/sqlserver/2004/07/showplan' AS sp)
  1243. select @output = @output + N'SOURCE: (' + @node_data.value('(./sp:RemoteModify/@RemoteSource)[1]', 'nvarchar(256)') + N')'
  1244. end
  1245. if (@node_data.exist('declare namespace sp="http://schemas.microsoft.com/sqlserver/2004/07/showplan"; ./sp:RemoteModify/@RemoteObject') = 1)
  1246. begin
  1247. ;WITH XMLNAMESPACES ('http://schemas.microsoft.com/sqlserver/2004/07/showplan' AS sp)
  1248. select @output = @output + N'OBJECT: (' + @node_data.value('(./sp:RemoteModify/@RemoteObject)[1]', 'nvarchar(256)') + N')'
  1249. end
  1250. if (@node_data.exist('declare namespace sp="http://schemas.microsoft.com/sqlserver/2004/07/showplan"; ./sp:RemoteModify/sp:SetPredicate') = 1)
  1251. begin
  1252. ;WITH XMLNAMESPACES ('http://schemas.microsoft.com/sqlserver/2004/07/showplan' AS sp)
  1253. select @output = @output + N'WHERE: (' + MS_PerfDashboard.fn_ShowplanBuildScalarExpression(@node_data.query('./sp:RemoteModify/sp:SetPredicate/*')) + N')'
  1254. end
  1255. select @output = @output + N')'
  1256. return @output;
  1257. end
  1258. go
  1259. if OBJECTPROPERTY(object_id('MS_PerfDashboard.fn_ShowplanFormatSort'), 'IsScalarFunction') = 1
  1260. drop function MS_PerfDashboard.fn_ShowplanFormatSort
  1261. go
  1262. CREATE FUNCTION MS_PerfDashboard.fn_ShowplanFormatSort(@node_data xml, @logical_op nvarchar(128))
  1263. RETURNS nvarchar(max)
  1264. as
  1265. begin
  1266. declare @output nvarchar(max)
  1267. select @output = N'Sort('
  1268. if @logical_op = N'Sort'
  1269. begin
  1270. if (@node_data.exist('declare namespace sp="http://schemas.microsoft.com/sqlserver/2004/07/showplan"; ./sp:Sort[@Distinct = 1]') = 1)
  1271. begin
  1272. select @output = @output + N'DISTINCT '
  1273. end
  1274. ;WITH XMLNAMESPACES ('http://schemas.microsoft.com/sqlserver/2004/07/showplan' AS sp)
  1275. select @output = @output + N'ORDER BY: (' + MS_PerfDashboard.fn_ShowplanBuildOrderBy(@node_data.query('./sp:Sort/sp:OrderBy/sp:OrderByColumn')) + N')'
  1276. end
  1277. else if @logical_op = N'TopN Sort'
  1278. begin
  1279. select @output = @output + N'TOP ' + @node_data.value('declare namespace sp="http://schemas.microsoft.com/sqlserver/2004/07/showplan"; (./sp:TopSort/@Rows)[1]', 'nvarchar(50)') + N', '
  1280. if (@node_data.exist('declare namespace sp="http://schemas.microsoft.com/sqlserver/2004/07/showplan"; ./sp:TopSort[@Distinct = 1]') = 1)
  1281. begin
  1282. select @output = @output + N'DISTINCT '
  1283. end
  1284. ;WITH XMLNAMESPACES ('http://schemas.microsoft.com/sqlserver/2004/07/showplan' AS sp)
  1285. select @output = @output + N'ORDER BY: (' + MS_PerfDashboard.fn_ShowplanBuildOrderBy(@node_data.query('./sp:TopSort/sp:OrderBy/sp:OrderByColumn')) + N')'
  1286. end
  1287. else if @logical_op = N'Distinct Sort'
  1288. begin
  1289. select @output = @output + N'DISTINCT '
  1290. ;WITH XMLNAMESPACES ('http://schemas.microsoft.com/sqlserver/2004/07/showplan' AS sp)
  1291. select @output = @output + N'ORDER BY: (' + MS_PerfDashboard.fn_ShowplanBuildOrderBy(@node_data.query('./sp:Sort/sp:OrderBy/sp:OrderByColumn')) + N')'
  1292. end
  1293. select @output = @output + N')'
  1294. return @output;
  1295. end
  1296. go
  1297. if OBJECTPROPERTY(object_id('MS_PerfDashboard.fn_ShowplanFormatSplit'), 'IsScalarFunction') = 1
  1298. drop function MS_PerfDashboard.fn_ShowplanFormatSplit
  1299. go
  1300. CREATE FUNCTION MS_PerfDashboard.fn_ShowplanFormatSplit(@node_data xml)
  1301. RETURNS nvarchar(max)
  1302. as
  1303. begin
  1304. declare @output nvarchar(max)
  1305. select @output = N'Split'
  1306. if (@node_data.exist('declare namespace sp="http://schemas.microsoft.com/sqlserver/2004/07/showplan"; ./sp:Split/sp:ActionColumn') = 1)
  1307. begin
  1308. ;WITH XMLNAMESPACES ('http://schemas.microsoft.com/sqlserver/2004/07/showplan' AS sp)
  1309. select @output = @output + N'(' + MS_PerfDashboard.fn_ShowplanBuildColumnReferenceList(@node_data.query('./sp:Split/sp:ActionColumn/sp:ColumnReference'), 0x1) + N')'
  1310. end
  1311. return @output;
  1312. end
  1313. go
  1314. if OBJECTPROPERTY(object_id('MS_PerfDashboard.fn_ShowplanFormatStreamAggregate'), 'IsScalarFunction') = 1
  1315. drop function MS_PerfDashboard.fn_ShowplanFormatStreamAggregate
  1316. go
  1317. CREATE FUNCTION MS_PerfDashboard.fn_ShowplanFormatStreamAggregate(@node_data xml)
  1318. RETURNS nvarchar(max)
  1319. as
  1320. begin
  1321. declare @output nvarchar(max)
  1322. declare @need_comma bit
  1323. select @output = N'Stream Aggregate('
  1324. if (@node_data.exist('declare namespace sp="http://schemas.microsoft.com/sqlserver/2004/07/showplan"; ./sp:StreamAggregate/sp:GroupBy') = 1)
  1325. begin
  1326. ;WITH XMLNAMESPACES ('http://schemas.microsoft.com/sqlserver/2004/07/showplan' AS sp)
  1327. select @output = @output + N'GROUP BY: (' + MS_PerfDashboard.fn_ShowplanBuildColumnReferenceList(@node_data.query('./sp:StreamAggregate/sp:GroupBy/sp:ColumnReference'), 0x1) + N')'
  1328. select @need_comma = 0x1
  1329. end
  1330. ;WITH XMLNAMESPACES ('http://schemas.microsoft.com/sqlserver/2004/07/showplan' AS sp)
  1331. select @output = @output +
  1332. case when @need_comma = 0x1 then N', ' else N'' end
  1333. + N'DEFINE: (' + MS_PerfDashboard.fn_ShowplanBuildDefinedValuesList(@node_data.query('./sp:StreamAggregate/sp:DefinedValues/sp:DefinedValue')) + N')'
  1334. select @output = @output + N')'
  1335. return @output;
  1336. end
  1337. go
  1338. if OBJECTPROPERTY(object_id('MS_PerfDashboard.fn_ShowplanFormatSegment'), 'IsScalarFunction') = 1
  1339. drop function MS_PerfDashboard.fn_ShowplanFormatSegment
  1340. go
  1341. CREATE FUNCTION MS_PerfDashboard.fn_ShowplanFormatSegment(@node_data xml)
  1342. RETURNS nvarchar(max)
  1343. as
  1344. begin
  1345. declare @output nvarchar(max)
  1346. select @output = N'Segment'
  1347. if (@node_data.exist('declare namespace sp="http://schemas.microsoft.com/sqlserver/2004/07/showplan"; ./sp:Segment/sp:GroupBy/sp:ColumnReference') = 1)
  1348. begin
  1349. ;WITH XMLNAMESPACES ('http://schemas.microsoft.com/sqlserver/2004/07/showplan' AS sp)
  1350. select @output = @output + N'(GROUP BY: ' + MS_PerfDashboard.fn_ShowplanBuildColumnReferenceList(@node_data.query('./sp:Segment/sp:GroupBy/sp:ColumnReference'), 0x1) + N')'
  1351. end
  1352. return @output;
  1353. end
  1354. go
  1355. if OBJECTPROPERTY(object_id('MS_PerfDashboard.fn_ShowplanFormatSpool'), 'IsScalarFunction') = 1
  1356. drop function MS_PerfDashboard.fn_ShowplanFormatSpool
  1357. go
  1358. CREATE FUNCTION MS_PerfDashboard.fn_ShowplanFormatSpool(@node_data xml, @physical_op nvarchar(128))
  1359. RETURNS nvarchar(max)
  1360. as
  1361. begin
  1362. declare @output nvarchar(max)
  1363. select @output = @physical_op
  1364. if (@node_data.exist('declare namespace sp="http://schemas.microsoft.com/sqlserver/2004/07/showplan"; ./sp:Spool/sp:SeekPredicate') = 1)
  1365. begin
  1366. ;WITH XMLNAMESPACES ('http://schemas.microsoft.com/sqlserver/2004/07/showplan' AS sp)
  1367. select @output = @output + N'(' + MS_PerfDashboard.fn_ShowplanBuildSeekPredicate(@node_data.query('./sp:Spool/sp:SeekPredicate/*')) + N')'
  1368. end
  1369. if (@node_data.exist('declare namespace sp="http://schemas.microsoft.com/sqlserver/2004/07/showplan"; ./sp:Spool[@Stack = 1]') = 1)
  1370. begin
  1371. select @output = @output + N' WITH STACK'
  1372. end
  1373. return @output;
  1374. end
  1375. go
  1376. if OBJECTPROPERTY(object_id('MS_PerfDashboard.fn_ShowplanFormatTableScan'), 'IsScalarFunction') = 1
  1377. drop function MS_PerfDashboard.fn_ShowplanFormatTableScan
  1378. go
  1379. CREATE FUNCTION MS_PerfDashboard.fn_ShowplanFormatTableScan(@node_data xml)
  1380. RETURNS nvarchar(max)
  1381. as
  1382. begin
  1383. declare @output nvarchar(max)
  1384. select @output = N'Table Scan('
  1385. ;WITH XMLNAMESPACES ('http://schemas.microsoft.com/sqlserver/2004/07/showplan' AS sp)
  1386. select @output = @output + MS_PerfDashboard.fn_ShowplanBuildObject(@node_data.query('./sp:TableScan/sp:Object'))
  1387. if (@node_data.exist('declare namespace sp="http://schemas.microsoft.com/sqlserver/2004/07/showplan"; ./sp:TableScan/sp:Predicate') = 1)
  1388. begin
  1389. ;WITH XMLNAMESPACES ('http://schemas.microsoft.com/sqlserver/2004/07/showplan' AS sp)
  1390. select @output = @output + N', WHERE: (' + MS_PerfDashboard.fn_ShowplanBuildScalarExpression(@node_data.query('./sp:TableScan/sp:Predicate/*')) + N')'
  1391. end
  1392. select @output = @output + N')'
  1393. if (@node_data.exist('declare namespace sp="http://schemas.microsoft.com/sqlserver/2004/07/showplan"; ./sp:TableScan[@Ordered = 1]') = 1)
  1394. begin
  1395. select @output = @output + N' ORDERED'
  1396. end
  1397. if (@node_data.exist('declare namespace sp="http://schemas.microsoft.com/sqlserver/2004/07/showplan"; ./sp:TableScan[@ForcedIndex = 1]') = 1)
  1398. begin
  1399. select @output = @output + N' FORCEDINDEX'
  1400. end
  1401. return @output;
  1402. end
  1403. go
  1404. if OBJECTPROPERTY(object_id('MS_PerfDashboard.fn_ShowplanFormatTop'), 'IsScalarFunction') = 1
  1405. drop function MS_PerfDashboard.fn_ShowplanFormatTop
  1406. go
  1407. CREATE FUNCTION MS_PerfDashboard.fn_ShowplanFormatTop(@node_data xml)
  1408. RETURNS nvarchar(max)
  1409. as
  1410. begin
  1411. declare @output nvarchar(max)
  1412. select @output = N'Top'
  1413. if (@node_data.exist('declare namespace sp="http://schemas.microsoft.com/sqlserver/2004/07/showplan"; ./sp:Top/sp:TopExpression') = 1)
  1414. begin
  1415. ;WITH XMLNAMESPACES ('http://schemas.microsoft.com/sqlserver/2004/07/showplan' AS sp)
  1416. select @output = @output + N'(TOP EXPRESSION: ' + MS_PerfDashboard.fn_ShowplanBuildScalarExpression(@node_data.query('./sp:Top/sp:TopExpression/*')) + N')'
  1417. end
  1418. return @output;
  1419. end
  1420. go
  1421. if OBJECTPROPERTY(object_id('MS_PerfDashboard.fn_ShowplanFormatTVF'), 'IsScalarFunction') = 1
  1422. drop function MS_PerfDashboard.fn_ShowplanFormatTVF
  1423. go
  1424. CREATE FUNCTION MS_PerfDashboard.fn_ShowplanFormatTVF(@node_data xml)
  1425. RETURNS nvarchar(max)
  1426. as
  1427. begin
  1428. declare @output nvarchar(max)
  1429. select @output = N'Table-valued Function('
  1430. if (@node_data.exist('declare namespace sp="http://schemas.microsoft.com/sqlserver/2004/07/showplan"; ./sp:TableValuedFunction/sp:Object') = 1)
  1431. begin
  1432. ;WITH XMLNAMESPACES ('http://schemas.microsoft.com/sqlserver/2004/07/showplan' AS sp)
  1433. select @output = @output + N'OBJECT: (' + MS_PerfDashboard.fn_ShowplanBuildObject(@node_data.query('./sp:TableValuedFunction/sp:Object')) + N')'
  1434. end
  1435. if (@node_data.exist('declare namespace sp="http://schemas.microsoft.com/sqlserver/2004/07/showplan"; ./sp:TableValuedFunction/sp:Predicate') = 1)
  1436. begin
  1437. ;WITH XMLNAMESPACES ('http://schemas.microsoft.com/sqlserver/2004/07/showplan' AS sp)
  1438. select @output = @output + N', WHERE: ( ' + MS_PerfDashboard.fn_ShowplanBuildPredicate(@node_data.query('./sp:TableValuedFunction/sp:Predicate')) + N')'
  1439. end
  1440. select @output = @output + N')'
  1441. return @output;
  1442. end
  1443. go
  1444. if OBJECTPROPERTY(object_id('MS_PerfDashboard.fn_ShowplanFormatUDX'), 'IsScalarFunction') = 1
  1445. drop function MS_PerfDashboard.fn_ShowplanFormatUDX
  1446. go
  1447. CREATE FUNCTION MS_PerfDashboard.fn_ShowplanFormatUDX(@node_data xml)
  1448. RETURNS nvarchar(max)
  1449. as
  1450. begin
  1451. declare @output nvarchar(max)
  1452. ;WITH XMLNAMESPACES ('http://schemas.microsoft.com/sqlserver/2004/07/showplan' AS sp)
  1453. select @output = N'UDX(' + @node_data.value('(./sp:Extension/@UDXName)[1]', 'nvarchar(128)') + N')'
  1454. return @output;
  1455. end
  1456. go
  1457. if OBJECTPROPERTY(object_id('MS_PerfDashboard.fn_ShowplanFormatUpdate'), 'IsScalarFunction') = 1
  1458. drop function MS_PerfDashboard.fn_ShowplanFormatUpdate
  1459. go
  1460. CREATE FUNCTION MS_PerfDashboard.fn_ShowplanFormatUpdate(@node_data xml, @physical_op nvarchar(128))
  1461. RETURNS nvarchar(max)
  1462. as
  1463. begin
  1464. declare @output nvarchar(max)
  1465. ;WITH XMLNAMESPACES ('http://schemas.microsoft.com/sqlserver/2004/07/showplan' AS sp)
  1466. select @output = @physical_op + N'(' + MS_PerfDashboard.fn_ShowplanBuildObject(@node_data.query('./sp:Object/*'))
  1467. if (@node_data.exist('declare namespace sp="http://schemas.microsoft.com/sqlserver/2004/07/showplan"; ./sp:SetPredicate') = 1)
  1468. begin
  1469. ;WITH XMLNAMESPACES ('http://schemas.microsoft.com/sqlserver/2004/07/showplan' AS sp)
  1470. select @output = @output + N'SET: ' + MS_PerfDashboard.fn_ShowplanBuildScalarExpression(@node_data.query('./sp:SetPredicate/*'))
  1471. end
  1472. select @output = @output + N')'
  1473. return @output;
  1474. end
  1475. go
  1476. if OBJECTPROPERTY(object_id('MS_PerfDashboard.fn_ShowplanFormatRIDLookup'), 'IsScalarFunction') = 1
  1477. drop function MS_PerfDashboard.fn_ShowplanFormatRIDLookup
  1478. go
  1479. CREATE FUNCTION MS_PerfDashboard.fn_ShowplanFormatRIDLookup(@node_data xml)
  1480. RETURNS nvarchar(max)
  1481. as
  1482. begin
  1483. declare @output nvarchar(max) = '';
  1484. if (@node_data.exist('declare namespace sp="http://schemas.microsoft.com/sqlserver/2004/07/showplan"; ./sp:IndexScan') = 1)
  1485. begin
  1486. ;WITH XMLNAMESPACES ('http://schemas.microsoft.com/sqlserver/2004/07/showplan' AS sp)
  1487. select @output = @output + MS_PerfDashboard.fn_ShowplanFormatIndexScan(@node_data.query('./sp:IndexScan'), 'RID Lookup')
  1488. select @output = @output + N')'
  1489. end
  1490. return @output;
  1491. end
  1492. go
  1493. if OBJECTPROPERTY(object_id('MS_PerfDashboard.fn_ShowplanFormatGenericUpdate'), 'IsScalarFunction') = 1
  1494. drop function MS_PerfDashboard.fn_ShowplanFormatGenericUpdate
  1495. go
  1496. CREATE FUNCTION MS_PerfDashboard.fn_ShowplanFormatGenericUpdate(@node_data xml, @physical_op nvarchar(128))
  1497. RETURNS nvarchar(max)
  1498. as
  1499. begin
  1500. declare @output nvarchar(max)
  1501. if (@node_data.exist('declare namespace sp="http://schemas.microsoft.com/sqlserver/2004/07/showplan"; ./sp:SimpleUpdate') = 1)
  1502. begin
  1503. ;WITH XMLNAMESPACES ('http://schemas.microsoft.com/sqlserver/2004/07/showplan' AS sp)
  1504. select @output = MS_PerfDashboard.fn_ShowplanFormatSimpleUpdate(@node_data.query('./sp:SimpleUpdate/*'), @physical_op)
  1505. end
  1506. if (@node_data.exist('declare namespace sp="http://schemas.microsoft.com/sqlserver/2004/07/showplan"; ./sp:Update') = 1)
  1507. begin
  1508. ;WITH XMLNAMESPACES ('http://schemas.microsoft.com/sqlserver/2004/07/showplan' AS sp)
  1509. select @output = MS_PerfDashboard.fn_ShowplanFormatUpdate(@node_data.query('./sp:Update/*'), @physical_op)
  1510. end
  1511. if (@node_data.exist('declare namespace sp="http://schemas.microsoft.com/sqlserver/2004/07/showplan"; ./sp:ScalarInsert') = 1)
  1512. begin
  1513. ;WITH XMLNAMESPACES ('http://schemas.microsoft.com/sqlserver/2004/07/showplan' AS sp)
  1514. select @output = @physical_op + '(' + MS_PerfDashboard.fn_ShowplanBuildScalarExpression(@node_data.query('./sp:ScalarInsert/sp:SetPredicate/*')) + ')'
  1515. end
  1516. return @output;
  1517. end
  1518. go
  1519. --
  1520. -- Created last since it depends on all the above functions for building/formatting the showplan
  1521. --
  1522. if OBJECTPROPERTY(object_id('MS_PerfDashboard.fn_ShowplanRowDetails'), 'IsTableFunction') = 1
  1523. drop function MS_PerfDashboard.fn_ShowplanRowDetails
  1524. go
  1525. CREATE FUNCTION MS_PerfDashboard.fn_ShowplanRowDetails(@relop_node xml)
  1526. returns @node TABLE (node_id int, stmt_text nvarchar(max), logical_op nvarchar(128), physical_op nvarchar(128), output_list nvarchar(max), avg_row_size float, est_cpu float, est_io float, est_rows float, est_rewinds float, est_rebinds float, est_subtree_cost float, warnings nvarchar(max))
  1527. AS
  1528. begin
  1529. declare @node_id int
  1530. declare @output_list nvarchar(max)
  1531. declare @stmt_text nvarchar(max)
  1532. declare @logical_op nvarchar(128), @physical_op nvarchar(128)
  1533. declare @avg_row_size float, @est_cpu float, @est_io float, @est_rows float, @est_rewinds float, @est_rebinds float, @est_subtree_cost float
  1534. declare @relop_children xml
  1535. ;WITH XMLNAMESPACES ('http://schemas.microsoft.com/sqlserver/2004/07/showplan' AS sp)
  1536. select @logical_op = @relop_node.value('(./sp:RelOp/@LogicalOp)[1]', 'nvarchar(128)'),
  1537. @physical_op = @relop_node.value('(./sp:RelOp/@PhysicalOp)[1]', 'nvarchar(128)'),
  1538. @relop_children = @relop_node.query('./sp:RelOp/*')
  1539. ;WITH XMLNAMESPACES ('http://schemas.microsoft.com/sqlserver/2004/07/showplan' AS sp)
  1540. select @stmt_text =
  1541. case
  1542. when @physical_op = N'Assert' then MS_PerfDashboard.fn_ShowplanFormatAssert(@relop_children)
  1543. when @physical_op = N'Bitmap' then MS_PerfDashboard.fn_ShowplanFormatBitmap(@relop_children)
  1544. when @physical_op in (N'Clustered Index Delete', N'Clustered Index Insert', N'Clustered Index Update', N'Clustered Index Merge',
  1545. N'Index Delete', N'Index Insert', N'Index Update',
  1546. N'Table Delete', N'Table Insert', N'Table Update') then MS_PerfDashboard.fn_ShowplanFormatGenericUpdate(@relop_children, @physical_op)
  1547. when @physical_op in (N'Clustered Index Scan', N'Clustered Index Seek',
  1548. N'Index Scan', N'Index Seek') then MS_PerfDashboard.fn_ShowplanFormatIndexScan(@relop_children, @physical_op)
  1549. -- when @physical_op = N'Clustered Update' then
  1550. when @physical_op = N'Collapse' then N'Collapse'
  1551. when @physical_op = N'Compute Scalar' then MS_PerfDashboard.fn_ShowplanFormatComputeScalar(@relop_children.query('./sp:ComputeScalar/*'), @physical_op)
  1552. when @physical_op = N'Concatenation' then MS_PerfDashboard.fn_ShowplanFormatConcat(@relop_children)
  1553. when @physical_op = N'Constant Scan' then MS_PerfDashboard.fn_ShowplanFormatConstantScan(@relop_children)
  1554. when @physical_op = N'Deleted Scan' then MS_PerfDashboard.fn_ShowplanFormatDeletedInsertedScan(@relop_children.query('./sp:DeletedScan/*'), @physical_op)
  1555. when @physical_op = N'Filter' then MS_PerfDashboard.fn_ShowplanFormatFilter(@relop_children)
  1556. -- when @physical_op = N'Generic' then
  1557. when @physical_op = N'Hash Match' then MS_PerfDashboard.fn_ShowplanFormatHashMatch(@relop_children, @logical_op)
  1558. when @physical_op = N'Index Spool' then MS_PerfDashboard.fn_ShowplanFormatSpool(@relop_children, @physical_op)
  1559. when @physical_op = N'Inserted Scan' then MS_PerfDashboard.fn_ShowplanFormatDeletedInsertedScan(@relop_children.query('./sp:InsertedScan/*'), @physical_op)
  1560. when @physical_op = N'Log Row Scan' then N'Log Row Scan'
  1561. when @physical_op = N'Merge Interval' then N'Merge Interval'
  1562. when @physical_op = N'Merge Join' then MS_PerfDashboard.fn_ShowplanFormatMerge(@relop_children, @logical_op)
  1563. when @physical_op = N'Nested Loops' then MS_PerfDashboard.fn_ShowplanFormatNestedLoops(@relop_children, @logical_op)
  1564. when @physical_op = N'Online Index Insert' then N'Online Index Insert'
  1565. when @physical_op = N'Parallelism' then MS_PerfDashboard.fn_ShowplanFormatParallelism(@relop_children, @logical_op)
  1566. when @physical_op = N'Parameter Table Scan' then N'Parameter Table Scan'
  1567. when @physical_op = N'Print' then N'Print'
  1568. when @physical_op in (N'Remote Delete', N'Remote Insert', N'Remote Update') then MS_PerfDashboard.fn_ShowplanFormatRemoteModify(@relop_children, @logical_op)
  1569. when @physical_op = N'Remote Scan' then MS_PerfDashboard.fn_ShowplanFormatRemoteScan(@relop_children)
  1570. when @physical_op = N'Remote Query' then MS_PerfDashboard.fn_ShowplanFormatRemoteQuery(@relop_children)
  1571. when @physical_op = N'RID Lookup' then MS_PerfDashboard.fn_ShowplanFormatRIDLookup(@relop_children)
  1572. when @physical_op = N'Row Count Spool' then MS_PerfDashboard.fn_ShowplanFormatSpool(@relop_children, @physical_op)
  1573. when @physical_op = N'Segment' then MS_PerfDashboard.fn_ShowplanFormatSegment(@relop_children)
  1574. when @physical_op = N'Sequence' then N'Sequence'
  1575. when @physical_op = N'Sequence Project' then MS_PerfDashboard.fn_ShowplanFormatComputeScalar(@relop_children.query('./sp:SequenceProject/*'), @physical_op)
  1576. when @physical_op = N'Sort' then MS_PerfDashboard.fn_ShowplanFormatSort(@relop_children, @logical_op)
  1577. when @physical_op = N'Split' then MS_PerfDashboard.fn_ShowplanFormatSplit(@relop_children)
  1578. when @physical_op = N'Stream Aggregate' then MS_PerfDashboard.fn_ShowplanFormatStreamAggregate(@relop_children)
  1579. when @physical_op = N'Switch' then N'Switch'
  1580. when @physical_op = N'Table-valued function' then MS_PerfDashboard.fn_ShowplanFormatTVF(@relop_children)
  1581. when @physical_op = N'Table Scan' then MS_PerfDashboard.fn_ShowplanFormatTableScan(@relop_children)
  1582. when @physical_op = N'Table Spool' then MS_PerfDashboard.fn_ShowplanFormatSpool(@relop_children, @physical_op)
  1583. when @physical_op = N'Table Merge' then N'Table Merge'
  1584. when @physical_op = N'Top' then MS_PerfDashboard.fn_ShowplanFormatTop(@relop_children)
  1585. when @physical_op = N'UDX' then MS_PerfDashboard.fn_ShowplanFormatUDX(@relop_children)
  1586. else @physical_op + N'(' + @logical_op + N')'
  1587. end
  1588. ;WITH XMLNAMESPACES ('http://schemas.microsoft.com/sqlserver/2004/07/showplan' AS sp)
  1589. insert @node (
  1590. node_id,
  1591. stmt_text,
  1592. logical_op,
  1593. physical_op,
  1594. output_list,
  1595. avg_row_size,
  1596. est_cpu,
  1597. est_io,
  1598. est_rows,
  1599. est_rewinds,
  1600. est_rebinds,
  1601. est_subtree_cost,
  1602. warnings)
  1603. values (
  1604. @relop_node.value('(./sp:RelOp/@NodeId)[1]', 'int'),
  1605. @stmt_text,
  1606. @logical_op,
  1607. @physical_op,
  1608. MS_PerfDashboard.fn_ShowplanBuildColumnReferenceList(@relop_node.query('./sp:RelOp/sp:OutputList/sp:ColumnReference'), 0x1),
  1609. @relop_node.value('(./sp:RelOp/@AvgRowSize)[1]', 'float'),
  1610. @relop_node.value('(./sp:RelOp/@EstimateCPU)[1]', 'float'),
  1611. @relop_node.value('(./sp:RelOp/@EstimateIO)[1]', 'float'),
  1612. @relop_node.value('(./sp:RelOp/@EstimateRows)[1]', 'float'),
  1613. @relop_node.value('(./sp:RelOp/@EstimateRewinds)[1]', 'float'),
  1614. @relop_node.value('(./sp:RelOp/@EstimateRebinds)[1]', 'float'),
  1615. @relop_node.value('(./sp:RelOp/@EstimatedTotalSubtreeCost)[1]', 'float'),
  1616. MS_PerfDashboard.fn_ShowplanBuildWarnings(@relop_node)
  1617. );
  1618. return;
  1619. end
  1620. go
  1621. if object_id('MS_PerfDashboard.usp_DatabaseOverview', 'P') is not null
  1622. drop procedure MS_PerfDashboard.usp_DatabaseOverview
  1623. go
  1624. create procedure MS_PerfDashboard.usp_DatabaseOverview
  1625. as
  1626. begin
  1627. select d.name, d.database_id, d.compatibility_level, d.recovery_model_desc,
  1628. s.[Data File(s) Size (KB)] / 1024.0 as [Data File(s) Size (MB)],
  1629. s.[Log File(s) Size (KB)] / 1024.0 as [Log File(s) Size (MB)],
  1630. s.[Percent Log Used],
  1631. d.is_auto_create_stats_on,
  1632. d.is_auto_update_stats_on,
  1633. d.is_auto_update_stats_async_on,
  1634. d.is_parameterization_forced,
  1635. d.page_verify_option_desc,
  1636. d.log_reuse_wait_desc
  1637. from sys.databases d
  1638. left join (select * from (select instance_name as database_name, counter_name, cntr_value
  1639. from sys.dm_os_performance_counters
  1640. where object_name like '%:Databases%' and counter_name in ('Data File(s) Size (KB)', 'Log File(s) Size (KB)', 'Percent Log Used')
  1641. and instance_name != '_Total') p
  1642. pivot (min(cntr_value) for counter_name in ([Data File(s) Size (KB)], [Log File(s) Size (KB)], [Percent Log Used])) as q) as s
  1643. on d.name = s.database_name
  1644. end
  1645. go
  1646. GRANT EXECUTE ON MS_PerfDashboard.usp_DatabaseOverview TO public
  1647. go
  1648. if object_id('MS_PerfDashboard.usp_LargeIOObjects', 'P') is not null
  1649. drop procedure MS_PerfDashboard.usp_LargeIOObjects
  1650. go
  1651. create procedure MS_PerfDashboard.usp_LargeIOObjects
  1652. as
  1653. begin
  1654. select db_name(d.database_id) as database_name,
  1655. quotename(object_schema_name(d.object_id, d.database_id)) + N'.' + quotename(object_name(d.object_id, d.database_id)) as object_name,
  1656. d.database_id,
  1657. d.object_id,
  1658. d.page_io_latch_wait_count,
  1659. d.page_io_latch_wait_in_ms,
  1660. d.range_scans,
  1661. d.index_lookups,
  1662. case when mid.database_id is null then 'N' else 'Y' end as missing_index_identified
  1663. from (select
  1664. database_id,
  1665. object_id,
  1666. row_number() over (partition by database_id order by sum(page_io_latch_wait_in_ms) desc) as row_number,
  1667. sum(page_io_latch_wait_count) as page_io_latch_wait_count,
  1668. sum(page_io_latch_wait_in_ms) as page_io_latch_wait_in_ms,
  1669. sum(range_scan_count) as range_scans,
  1670. sum(singleton_lookup_count) as index_lookups
  1671. from sys.dm_db_index_operational_stats(NULL, NULL, NULL, NULL)
  1672. where page_io_latch_wait_count > 0
  1673. group by database_id, object_id ) as d
  1674. left join (select distinct database_id, object_id from sys.dm_db_missing_index_details) as mid
  1675. on mid.database_id = d.database_id and mid.object_id = d.object_id
  1676. where d.row_number <= 20
  1677. end
  1678. go
  1679. GRANT EXECUTE ON MS_PerfDashboard.usp_LargeIOObjects TO public
  1680. go
  1681. if object_id('MS_PerfDashboard.usp_DBFileIO', 'P') is not null
  1682. drop procedure MS_PerfDashboard.usp_DBFileIO
  1683. go
  1684. create procedure MS_PerfDashboard.usp_DBFileIO
  1685. as
  1686. begin
  1687. select
  1688. m.database_id,
  1689. db_name(m.database_id) as database_name,
  1690. m.file_id,
  1691. m.name as file_name,
  1692. m.physical_name,
  1693. m.type_desc,
  1694. fs.num_of_reads,
  1695. fs.num_of_bytes_read,
  1696. fs.io_stall_read_ms,
  1697. fs.num_of_writes,
  1698. fs.num_of_bytes_written,
  1699. fs.io_stall_write_ms
  1700. from sys.dm_io_virtual_file_stats(NULL, NULL) fs
  1701. join sys.master_files m on fs.database_id = m.database_id and fs.file_id = m.file_id
  1702. end
  1703. go
  1704. GRANT EXECUTE ON MS_PerfDashboard.usp_DBFileIO TO public
  1705. go
  1706. if object_id('MS_PerfDashboard.usp_DmOsWaitStats', 'P') is not null
  1707. drop procedure MS_PerfDashboard.usp_DmOsWaitStats
  1708. go
  1709. create procedure MS_PerfDashboard.usp_DmOsWaitStats
  1710. as
  1711. begin
  1712. select
  1713. wait_type,
  1714. msdb.MS_PerfDashboard.fn_WaitTypeCategory(wait_type) as wait_category,
  1715. waiting_tasks_count as num_waits,
  1716. wait_time_ms as wait_time,
  1717. max_wait_time_ms
  1718. from sys.dm_os_wait_stats
  1719. where waiting_tasks_count > 0
  1720. end
  1721. go
  1722. GRANT EXECUTE ON MS_PerfDashboard.usp_DmOsWaitStats TO public
  1723. go
  1724. if object_id('MS_PerfDashboard.usp_MissingIndexes', 'P') is not null
  1725. drop procedure MS_PerfDashboard.usp_MissingIndexes
  1726. go
  1727. create procedure MS_PerfDashboard.usp_MissingIndexes @showplan varchar(max)
  1728. as
  1729. begin
  1730. WITH XMLNAMESPACES ('http://schemas.microsoft.com/sqlserver/2004/07/showplan' AS sp)
  1731. SELECT
  1732. index_node.value('(../@Impact)[1]', 'float') as index_impact,
  1733. index_node.query('concat(
  1734. string((./@Database)[1]),
  1735. ".",
  1736. string((./@Schema)[1]),
  1737. ".",
  1738. string((./@Table)[1])
  1739. )') as target_object_name,
  1740. replace(convert(nvarchar(max), index_node.query('for $colgroup in ./sp:ColumnGroup,
  1741. $col in $colgroup/sp:Column
  1742. where $colgroup/@Usage = "EQUALITY"
  1743. return string($col/@Name)')), '] [', '],[') as equality_columns,
  1744. replace(convert(nvarchar(max), index_node.query('for $colgroup in ./sp:ColumnGroup,
  1745. $col in $colgroup/sp:Column
  1746. where $colgroup/@Usage = "INEQUALITY"
  1747. return string($col/@Name)')), '] [', '],[') as inequality_columns,
  1748. replace(convert(nvarchar(max), index_node.query('for $colgroup in .//sp:ColumnGroup,
  1749. $col in $colgroup/sp:Column
  1750. where $colgroup/@Usage = "INCLUDE"
  1751. return string($col/@Name)')), '] [', '],[') as included_columns
  1752. from (select convert(xml, @showplan) as xml_showplan) as t
  1753. outer apply t.xml_showplan.nodes('//sp:MissingIndexes/sp:MissingIndexGroup/sp:MissingIndex') as missing_indexes(index_node)
  1754. end
  1755. go
  1756. GRANT EXECUTE ON MS_PerfDashboard.usp_MissingIndexes TO public
  1757. go
  1758. if object_id('MS_PerfDashboard.usp_QueryText', 'P') is not null
  1759. drop procedure MS_PerfDashboard.usp_QueryText
  1760. go
  1761. create procedure MS_PerfDashboard.usp_QueryText @sql_handle varchar(8000), @stmt_start_offset int, @stmt_end_offset int
  1762. as
  1763. begin
  1764. select * from msdb.MS_PerfDashboard.fn_QueryTextFromHandle(msdb.MS_PerfDashboard.fn_hexstrtovarbin(@sql_handle), @stmt_start_offset, @stmt_end_offset);
  1765. end
  1766. go
  1767. GRANT EXECUTE ON MS_PerfDashboard.usp_QueryText TO public
  1768. go
  1769. if object_id('MS_PerfDashboard.usp_MissingIndexStats', 'P') is not null
  1770. drop procedure MS_PerfDashboard.usp_MissingIndexStats
  1771. go
  1772. create procedure MS_PerfDashboard.usp_MissingIndexStats @DatabaseID int, @ObjectID int
  1773. as
  1774. begin
  1775. select d.database_id, d.object_id, d.index_handle, d.equality_columns, d.inequality_columns, d.included_columns, d.statement as fully_qualified_object,
  1776. gs.*
  1777. from sys.dm_db_missing_index_groups g
  1778. join sys.dm_db_missing_index_group_stats gs on gs.group_handle = g.index_group_handle
  1779. join sys.dm_db_missing_index_details d on g.index_handle = d.index_handle
  1780. where d.database_id = isnull(@DatabaseID , d.database_id) and d.object_id = isnull(@ObjectID, d.object_id)
  1781. end
  1782. go
  1783. GRANT EXECUTE ON MS_PerfDashboard.usp_MissingIndexStats TO public
  1784. go
  1785. if object_id('MS_PerfDashboard.usp_QueryAttributes', 'P') is not null
  1786. drop procedure MS_PerfDashboard.usp_QueryAttributes
  1787. go
  1788. create procedure MS_PerfDashboard.usp_QueryAttributes @sql_handle varchar(8000), @stmt_start_offset int, @stmt_end_offset int
  1789. as
  1790. begin
  1791. select
  1792. qt.database_id,
  1793. quotename(db_name(qt.database_id)) as database_name,
  1794. qt.object_id,
  1795. quotename(object_schema_name(qt.object_id, qt.database_id)) + N'.' + quotename(object_name(qt.object_id, qt.database_id)) as qualified_object_name,
  1796. qt.encrypted,
  1797. qt.query_text
  1798. from msdb.MS_PerfDashboard.fn_QueryTextFromHandle(msdb.MS_PerfDashboard.fn_hexstrtovarbin(@sql_handle), @stmt_start_offset, @stmt_end_offset) as qt
  1799. end
  1800. go
  1801. GRANT EXECUTE ON MS_PerfDashboard.usp_QueryAttributes TO public
  1802. go
  1803. if object_id('MS_PerfDashboard.usp_ShowplanAttributes', 'P') is not null
  1804. drop procedure MS_PerfDashboard.usp_ShowplanAttributes
  1805. go
  1806. create procedure MS_PerfDashboard.usp_ShowplanAttributes @plan_handle nvarchar(256), @stmt_start_offset int, @stmt_end_offset int
  1807. as
  1808. begin
  1809. declare @plan_text nvarchar(max)
  1810. declare @plan_xml xml
  1811. declare @missing_index_count int
  1812. declare @plan_guide_name nvarchar(128)
  1813. declare @warnings_exist bit
  1814. declare @plan_dbid smallint
  1815. declare @plan_dbname nvarchar(128)
  1816. begin try
  1817. select @plan_dbid = convert(smallint, pa.value) from sys.dm_exec_plan_attributes(msdb.MS_PerfDashboard.fn_hexstrtovarbin(@plan_handle)) as pa where pa.attribute = 'dbid'
  1818. select @plan_dbname = quotename(db_name(@plan_dbid))
  1819. --plan_handle may now be invalid, or xml could be > 128 levels deep such that conversion fails
  1820. select @plan_text = p.query_plan from sys.dm_exec_text_query_plan(msdb.MS_PerfDashboard.fn_hexstrtovarbin(@plan_handle), @stmt_start_offset, @stmt_end_offset) as p
  1821. select @plan_xml = convert(xml, @plan_text)
  1822. ;WITH XMLNAMESPACES ('http://schemas.microsoft.com/sqlserver/2004/07/showplan' AS sp)
  1823. select @missing_index_count = @plan_xml.value('count(//sp:MissingIndexes/sp:MissingIndexGroup)', 'int'),
  1824. @plan_guide_name = @plan_xml.value('(//sp:StmtSimple/@PlanGuideName)[1]', 'nvarchar(128)'),
  1825. @warnings_exist = @plan_xml.exist('//sp:Warnings')
  1826. -- TODO: warning for optimizer timeout/memory abort: @StatementOptmEarlyAbortReason
  1827. end try
  1828. begin catch
  1829. select @plan_xml = NULL --something required in catch block, and this does no harm
  1830. end catch
  1831. select
  1832. @plan_text as query_plan,
  1833. @plan_dbid as plan_database_id,
  1834. @plan_dbname as plan_database_name,
  1835. @missing_index_count as missing_index_count,
  1836. @plan_guide_name as plan_guide_name,
  1837. @warnings_exist as warnings_exist
  1838. end
  1839. go
  1840. GRANT EXECUTE ON MS_PerfDashboard.usp_ShowplanAttributes TO public
  1841. go
  1842. if object_id('MS_PerfDashboard.usp_PlanParameters', 'P') is not null
  1843. drop procedure MS_PerfDashboard.usp_PlanParameters
  1844. go
  1845. create procedure MS_PerfDashboard.usp_PlanParameters @plan_handle nvarchar(256), @stmt_start_offset int, @stmt_end_offset int
  1846. as
  1847. begin
  1848. declare @plan_xml xml
  1849. begin try
  1850. -- convert may fail due to exceeding 128 depth limit
  1851. select @plan_xml = convert(xml, query_plan) from sys.dm_exec_text_query_plan(msdb.MS_PerfDashboard.fn_hexstrtovarbin(@plan_handle), @stmt_start_offset, @stmt_end_offset)
  1852. end try
  1853. begin catch
  1854. select @plan_xml = NULL
  1855. end catch
  1856. ;WITH XMLNAMESPACES ('http://schemas.microsoft.com/sqlserver/2004/07/showplan' AS sp)
  1857. SELECT
  1858. parameter_list.param_node.value('(./@Column)[1]', 'nvarchar(128)') as param_name,
  1859. parameter_list.param_node.value('(./@ParameterCompiledValue)[1]', 'nvarchar(max)') as param_compiled_value
  1860. from (select @plan_xml as xml_showplan) as t
  1861. outer apply t.xml_showplan.nodes('//sp:ParameterList/sp:ColumnReference') as parameter_list (param_node)
  1862. end
  1863. go
  1864. GRANT EXECUTE ON MS_PerfDashboard.usp_PlanParameters TO public
  1865. go
  1866. if object_id('MS_PerfDashboard.usp_QueryStatsTopN', 'P') is not null
  1867. drop procedure MS_PerfDashboard.usp_QueryStatsTopN
  1868. go
  1869. create procedure MS_PerfDashboard.usp_QueryStatsTopN @OrderBy_Criteria nvarchar(128)
  1870. as
  1871. begin
  1872. select
  1873. query_rank,
  1874. charted_value,
  1875. master.dbo.fn_varbintohexstr(sql_handle) as sql_handle,
  1876. master.dbo.fn_varbintohexstr(plan_handle) as plan_handle,
  1877. statement_start_offset,
  1878. statement_end_offset,
  1879. creation_time,
  1880. last_execution_time,
  1881. execution_count,
  1882. plan_generation_num,
  1883. total_worker_time,
  1884. last_worker_time,
  1885. min_worker_time,
  1886. max_worker_time,
  1887. total_physical_reads,
  1888. last_physical_reads,
  1889. min_physical_reads,
  1890. max_physical_reads,
  1891. total_logical_reads,
  1892. last_logical_reads,
  1893. min_logical_reads,
  1894. max_logical_reads,
  1895. total_logical_writes,
  1896. last_logical_writes,
  1897. min_logical_writes,
  1898. max_logical_writes,
  1899. total_clr_time,
  1900. last_clr_time,
  1901. min_clr_time,
  1902. max_clr_time,
  1903. total_elapsed_time,
  1904. last_elapsed_time,
  1905. min_elapsed_time,
  1906. max_elapsed_time,
  1907. case when LEN(qt.query_text) < 2048 then qt.query_text else LEFT(qt.query_text, 2048) + N'...' end as query_text
  1908. from (select s.*, row_number() over(order by charted_value desc, last_execution_time desc) as query_rank from
  1909. (select *,
  1910. CASE @OrderBy_Criteria
  1911. WHEN 'Logical Reads' then total_logical_reads
  1912. WHEN 'Physical Reads' then total_physical_reads
  1913. WHEN 'Logical Writes' then total_logical_writes
  1914. WHEN 'CPU' then total_worker_time / 1000
  1915. WHEN 'Duration' then total_elapsed_time / 1000
  1916. WHEN 'CLR Time' then total_clr_time / 1000
  1917. END as charted_value
  1918. from sys.dm_exec_query_stats) as s where s.charted_value > 0) as qs
  1919. cross apply msdb.MS_PerfDashboard.fn_QueryTextFromHandle(sql_handle, statement_start_offset, statement_end_offset) as qt
  1920. where qs.query_rank <= 20 -- return only top 20 entries
  1921. end
  1922. go
  1923. GRANT EXECUTE ON MS_PerfDashboard.usp_QueryStatsTopN TO public
  1924. go
  1925. if object_id('MS_PerfDashboard.usp_QueryStatsTopN1', 'P') is not null
  1926. drop procedure MS_PerfDashboard.usp_QueryStatsTopN1
  1927. go
  1928. create procedure MS_PerfDashboard.usp_QueryStatsTopN1 @OrderBy_Criteria nvarchar(128)
  1929. as
  1930. begin
  1931. SELECT
  1932. query_text,
  1933. master.dbo.fn_varbintohexstr(query_hash) query_hash,
  1934. master.dbo.fn_varbintohexstr(sql_handle) sql_handle,
  1935. statement_start_offset,
  1936. statement_end_offset,
  1937. querycount,
  1938. queryplanhashcount,
  1939. execution_count,
  1940. total_elapsed_time,
  1941. min_elapsed_time,
  1942. max_elapsed_time,
  1943. average_elapsed_time,
  1944. total_CPU_time,
  1945. min_CPU_time,
  1946. max_CPU_time,
  1947. average_CPU_time,
  1948. total_logical_reads,
  1949. min_logical_reads,
  1950. max_logical_reads,
  1951. average_logical_reads,
  1952. total_physical_reads,
  1953. min_physical_reads,
  1954. max_physical_reads,
  1955. average_physical_reads,
  1956. total_logical_writes,
  1957. min_logical_writes,
  1958. max_logical_writes,
  1959. average_logical_writes,
  1960. total_clr_time,
  1961. min_clr_time,
  1962. max_clr_time,
  1963. average_clr_time,
  1964. max_plan_generation_num,
  1965. earliest_creation_time,
  1966. query_rank,
  1967. charted_value,
  1968. master.dbo.fn_varbintohexstr(plan_handle) as plan_handle
  1969. FROM (SELECT s.*,
  1970. Row_number() OVER(ORDER BY charted_value DESC) AS query_rank
  1971. FROM (SELECT CASE @OrderBy_Criteria
  1972. WHEN 'Logical Reads' THEN SUM(total_logical_reads)
  1973. WHEN 'Physical Reads' THEN SUM(total_physical_reads)
  1974. WHEN 'Logical Writes' THEN SUM(total_logical_writes)
  1975. WHEN 'CPU' THEN SUM(total_worker_time) / 1000
  1976. WHEN 'Duration' THEN SUM(total_elapsed_time) / 1000
  1977. WHEN 'CLR Time' THEN SUM(total_clr_time) / 1000
  1978. END AS charted_value,
  1979. query_hash,
  1980. MAX(sql_handle_1) sql_handle,
  1981. MAX(statement_start_offset_1) statement_start_offset,
  1982. MAX(statement_end_offset_1) statement_end_offset,
  1983. COUNT(*) querycount,
  1984. COUNT (DISTINCT query_plan_hash) queryplanhashcount,
  1985. MAX(plan_handle_1) plan_handle,
  1986. MIN(creation_time) earliest_creation_time,
  1987. SUM(execution_count) execution_count,
  1988. SUM(total_elapsed_time) total_elapsed_time,
  1989. min(min_elapsed_time) min_elapsed_time,
  1990. max(max_elapsed_time) max_elapsed_time,
  1991. SUM(total_elapsed_time)/SUM(execution_count) average_elapsed_time,
  1992. SUM(total_worker_time) total_CPU_time,
  1993. min(min_worker_time) min_CPU_time,
  1994. max(max_worker_time) max_CPU_time,
  1995. SUM(total_worker_time)/SUM(execution_count) average_CPU_time,
  1996. SUM(total_logical_reads) total_logical_reads,
  1997. min(min_logical_reads) min_logical_reads,
  1998. max(max_logical_reads) max_logical_reads,
  1999. SUM(total_logical_reads)/SUM(execution_count) average_logical_reads,
  2000. SUM(total_physical_reads) total_physical_reads,
  2001. min(min_physical_reads) min_physical_reads,
  2002. max(max_physical_reads) max_physical_reads,
  2003. SUM(total_physical_reads)/SUM(execution_count) average_physical_reads,
  2004. SUM(total_logical_writes) total_logical_writes,
  2005. min(min_logical_writes) min_logical_writes,
  2006. max(max_logical_writes) max_logical_writes,
  2007. SUM(total_logical_writes)/SUM(execution_count) average_logical_writes,
  2008. SUM(total_clr_time) total_clr_time,
  2009. SUM(total_clr_time)/SUM(execution_count) average_clr_time,
  2010. min(min_clr_time) min_clr_time,
  2011. max(max_clr_time) max_clr_time,
  2012. MAX(plan_generation_num) max_plan_generation_num
  2013. FROM (
  2014. -- Implement my own FIRST aggregate to get consistent values for sql_handle, start/end offsets of
  2015. -- an arbitrary first row for a given query_hash
  2016. SELECT
  2017. CASE when t.rownum = 1 THEN plan_handle ELSE NULL END as plan_handle_1,
  2018. CASE WHEN t.rownum = 1 THEN sql_handle ELSE NULL END AS sql_handle_1,
  2019. CASE WHEN t.rownum = 1 THEN statement_start_offset ELSE NULL END AS statement_start_offset_1,
  2020. CASE WHEN t.rownum = 1 THEN statement_end_offset ELSE NULL END AS statement_end_offset_1,
  2021. *
  2022. FROM (SELECT row_number() OVER (PARTITION BY query_hash ORDER BY sql_handle) AS rownum, *
  2023. FROM sys.dm_exec_query_stats) AS t) AS t2
  2024. GROUP BY query_hash
  2025. ) AS s
  2026. WHERE s.charted_value > 0
  2027. ) AS qs
  2028. CROSS APPLY msdb.MS_PerfDashboard.fn_QueryTextFromHandle(qs.sql_handle,
  2029. qs.statement_start_offset, qs.statement_end_offset) AS qt
  2030. where query_rank <= 20
  2031. order by charted_value desc
  2032. end
  2033. go
  2034. GRANT EXECUTE ON MS_PerfDashboard.usp_QueryStatsTopN1 TO public
  2035. go
  2036. if object_id('MS_PerfDashboard.usp_QueryStatsRecentActivity', 'P') is not null
  2037. drop procedure MS_PerfDashboard.usp_QueryStatsRecentActivity
  2038. go
  2039. create procedure MS_PerfDashboard.usp_QueryStatsRecentActivity @WithActivitySince datetime
  2040. as
  2041. begin
  2042. select
  2043. query_rank,
  2044. charted_value,
  2045. master.dbo.fn_varbintohexstr(sql_handle) as sql_handle,
  2046. master.dbo.fn_varbintohexstr(plan_handle) as plan_handle,
  2047. statement_start_offset,
  2048. statement_end_offset,
  2049. creation_time,
  2050. last_execution_time,
  2051. execution_count,
  2052. plan_generation_num,
  2053. total_worker_time,
  2054. last_worker_time,
  2055. min_worker_time,
  2056. max_worker_time,
  2057. total_physical_reads,
  2058. last_physical_reads,
  2059. min_physical_reads,
  2060. max_physical_reads,
  2061. total_logical_reads,
  2062. last_logical_reads,
  2063. min_logical_reads,
  2064. max_logical_reads,
  2065. total_logical_writes,
  2066. last_logical_writes,
  2067. min_logical_writes,
  2068. max_logical_writes,
  2069. total_clr_time,
  2070. last_clr_time,
  2071. min_clr_time,
  2072. max_clr_time,
  2073. total_elapsed_time,
  2074. last_elapsed_time,
  2075. min_elapsed_time,
  2076. max_elapsed_time,
  2077. case when LEN(qt.query_text) < 2048 then qt.query_text else LEFT(qt.query_text, 2048) + N'...' end as query_text
  2078. from (select s.*, row_number() over(order by charted_value desc, last_execution_time desc) as query_rank from
  2079. (select *, total_worker_time as charted_value
  2080. from sys.dm_exec_query_stats
  2081. where total_worker_time > 0 and last_execution_time > isnull(@WithActivitySince, cast('1900-01-01' as datetime))) as s) as qs
  2082. outer apply msdb.MS_PerfDashboard.fn_QueryTextFromHandle(sql_handle, statement_start_offset, statement_end_offset) as qt
  2083. where qs.query_rank <= 15 -- return only top 15 entries
  2084. end
  2085. go
  2086. GRANT EXECUTE ON MS_PerfDashboard.usp_QueryStatsRecentActivity TO public
  2087. go
  2088. if object_id('MS_PerfDashboard.usp_SessionRequestActivity', 'P') is not null
  2089. drop procedure MS_PerfDashboard.usp_SessionRequestActivity
  2090. go
  2091. create procedure MS_PerfDashboard.usp_SessionRequestActivity @WithActivitySince datetime, @IsUserProcess bit
  2092. as
  2093. begin
  2094. select avg_request_cpu_per_ms * request_ms_in_window as request_recent_cpu_est,
  2095. avg_session_cpu_per_ms * session_ms_in_window as session_recent_cpu_est,
  2096. d.*
  2097. from (select s.session_id,
  2098. r.request_id,
  2099. s.login_time,
  2100. -- s.host_name,
  2101. s.program_name,
  2102. s.login_name,
  2103. s.status as session_status,
  2104. s.last_request_start_time,
  2105. s.last_request_end_time,
  2106. s.cpu_time as session_cpu_time,
  2107. r.cpu_time as request_cpu_time,
  2108. -- s.logical_reads as session_logical_reads,
  2109. -- r.logical_reads as request_logical_reads,
  2110. r.start_time as request_start_time,
  2111. r.status as request_status,
  2112. r.command,
  2113. master.dbo.fn_varbintohexstr(r.sql_handle) as sql_handle,
  2114. master.dbo.fn_varbintohexstr(r.plan_handle) as plan_handle,
  2115. r.statement_start_offset,
  2116. r.statement_end_offset,
  2117. case when r.start_time > getdate() then convert(float, r.cpu_time) / msdb.MS_PerfDashboard.fn_DatediffMilliseconds(r.start_time, getdate()) else convert(float, 1.0) end as avg_request_cpu_per_ms,
  2118. isnull(msdb.MS_PerfDashboard.fn_DatediffMilliseconds(case when r.start_time < @WithActivitySince then @WithActivitySince else r.start_time end, getdate()), 0) as request_ms_in_window,
  2119. case when s.login_time > getdate() then convert(float, s.cpu_time) / (msdb.MS_PerfDashboard.fn_DatediffMilliseconds(s.login_time, getdate())) else convert(float, 1.0) end as avg_session_cpu_per_ms,
  2120. isnull(msdb.MS_PerfDashboard.fn_DatediffMilliseconds(case when s.login_time < @WithActivitySince then @WithActivitySince else s.login_time end, case when r.request_id is null then s.last_request_end_time else getdate() end), 0) as session_ms_in_window
  2121. from sys.dm_exec_sessions s
  2122. left join sys.dm_exec_requests as r on s.session_id = r.session_id
  2123. where (s.last_request_end_time > @WithActivitySince or r.request_id is not null) and (s.is_user_process = @IsUserProcess or s.is_user_process=1)) as d
  2124. where (avg_request_cpu_per_ms * request_ms_in_window) + (avg_session_cpu_per_ms * session_ms_in_window) > 1000.0
  2125. end
  2126. go
  2127. GRANT EXECUTE ON MS_PerfDashboard.usp_SessionRequestActivity TO public
  2128. go
  2129. if object_id('MS_PerfDashboard.usp_RequestDetails', 'P') is not null
  2130. drop procedure MS_PerfDashboard.usp_RequestDetails
  2131. go
  2132. create procedure MS_PerfDashboard.usp_RequestDetails @include_system_processes bit
  2133. as
  2134. begin
  2135. SELECT master.dbo.fn_varbintohexstr(sql_handle) AS sql_handle,
  2136. master.dbo.fn_varbintohexstr(plan_handle) AS plan_handle,
  2137. case when LEN(qt.query_text) < 2048 then qt.query_text else LEFT(qt.query_text, 2048) + N'...' end as query_text,
  2138. r.session_id,
  2139. r.request_id,
  2140. r.start_time,
  2141. r.status,
  2142. r.statement_start_offset,
  2143. r.statement_end_offset,
  2144. r.database_id,
  2145. r.blocking_session_id,
  2146. r.wait_type,
  2147. r.wait_time,
  2148. r.wait_resource,
  2149. r.last_wait_type,
  2150. r.open_transaction_count,
  2151. r.open_resultset_count,
  2152. r.transaction_id,
  2153. r.cpu_time,
  2154. r.total_elapsed_time,
  2155. r.scheduler_id,
  2156. r.reads,
  2157. r.writes,
  2158. r.logical_reads,
  2159. r.transaction_isolation_level,
  2160. r.granted_query_memory,
  2161. r.executing_managed_code
  2162. FROM sys.dm_exec_requests AS r
  2163. JOIN sys.dm_exec_sessions s on r.session_id = s.session_id
  2164. outer APPLY msdb.MS_PerfDashboard.fn_QueryTextFromHandle(sql_handle, statement_start_offset, statement_end_offset) as qt
  2165. WHERE s.is_user_process = CASE when @include_system_processes > 0 THEN s.is_user_process ELSE 1 END
  2166. end
  2167. go
  2168. GRANT EXECUTE ON MS_PerfDashboard.usp_RequestDetails TO public
  2169. go
  2170. if object_id('MS_PerfDashboard.usp_SessionData', 'P') is not null
  2171. drop procedure MS_PerfDashboard.usp_SessionData
  2172. go
  2173. create procedure MS_PerfDashboard.usp_SessionData @session_id int
  2174. as
  2175. begin
  2176. SELECT session_id, login_time, host_name, program_name, login_name, nt_domain,
  2177. nt_user_name, status, cpu_time, memory_usage, total_scheduled_time, total_elapsed_time, last_request_start_time,
  2178. last_request_end_time, reads, writes, logical_reads, is_user_process, text_size, language, date_format, date_first, quoted_identifier, arithabort,
  2179. ansi_null_dflt_on, ansi_defaults, ansi_warnings, ansi_padding, ansi_nulls, concat_null_yields_null, transaction_isolation_level, lock_timeout,
  2180. deadlock_priority, row_count, prev_error
  2181. FROM sys.dm_exec_sessions
  2182. WHERE session_id = @session_id
  2183. end
  2184. go
  2185. GRANT EXECUTE ON MS_PerfDashboard.usp_SessionData TO public
  2186. go
  2187. if object_id('MS_PerfDashboard.usp_SessionRequests', 'P') is not null
  2188. drop procedure MS_PerfDashboard.usp_SessionRequests
  2189. go
  2190. create procedure MS_PerfDashboard.usp_SessionRequests @session_id int
  2191. as
  2192. begin
  2193. select request_id,
  2194. master.dbo.fn_varbintohexstr(sql_handle) as sql_handle,
  2195. master.dbo.fn_varbintohexstr(plan_handle) as plan_handle,
  2196. statement_start_offset,
  2197. statement_end_offset,
  2198. qt.query_text,
  2199. start_time,
  2200. status,
  2201. command,
  2202. r.database_id,
  2203. blocking_session_id,
  2204. wait_type,
  2205. wait_time,
  2206. wait_resource,
  2207. cpu_time,
  2208. total_elapsed_time,
  2209. open_transaction_count,
  2210. transaction_id,
  2211. logical_reads,
  2212. reads,
  2213. writes
  2214. from sys.dm_exec_requests r
  2215. outer apply msdb.MS_PerfDashboard.fn_QueryTextFromHandle(sql_handle, statement_start_offset, statement_end_offset) as qt
  2216. where session_id = @session_id
  2217. end
  2218. go
  2219. GRANT EXECUTE ON MS_PerfDashboard.usp_SessionRequests TO public
  2220. go
  2221. if object_id('MS_PerfDashboard.usp_LastBatchForIdleSession', 'P') is not null
  2222. drop procedure MS_PerfDashboard.usp_LastBatchForIdleSession
  2223. go
  2224. create procedure MS_PerfDashboard.usp_LastBatchForIdleSession @session_id int
  2225. as
  2226. begin
  2227. if not exists (select * from sys.dm_exec_requests where session_id = @session_id)
  2228. begin
  2229. select t.dbid, db_name(t.dbid) as database_name, t.objectid, object_name(t.dbid, t.objectid) as object_name,
  2230. case when t.encrypted = 0 then t.text else N'encrypted' end as last_query
  2231. from sys.dm_exec_connections c
  2232. cross apply sys.dm_exec_sql_text(c.most_recent_sql_handle) as t
  2233. where c.most_recent_session_id = @session_id
  2234. end
  2235. else
  2236. begin
  2237. select cast(NULL as smallint), cast (NULL as sysname), cast(NULL as int), cast(NULL as sysname), cast(NULL as nvarchar(max)) where 0 = 1
  2238. end
  2239. end
  2240. go
  2241. GRANT EXECUTE ON MS_PerfDashboard.usp_LastBatchForIdleSession TO public
  2242. go
  2243. if object_id('MS_PerfDashboard.usp_SessionDetails', 'P') is not null
  2244. drop procedure MS_PerfDashboard.usp_SessionDetails
  2245. go
  2246. create procedure MS_PerfDashboard.usp_SessionDetails @include_system_processes bit
  2247. as
  2248. begin
  2249. select session_id,
  2250. login_name,
  2251. host_name,
  2252. program_name,
  2253. nt_domain,
  2254. nt_user_name,
  2255. status,
  2256. cpu_time,
  2257. memory_usage,
  2258. last_request_start_time,
  2259. last_request_end_time,
  2260. logical_reads,
  2261. reads,
  2262. writes,
  2263. is_user_process
  2264. from sys.dm_exec_sessions s
  2265. WHERE s.is_user_process = CASE when @include_system_processes > 0 THEN s.is_user_process ELSE 1 END
  2266. end
  2267. go
  2268. GRANT EXECUTE ON MS_PerfDashboard.usp_SessionDetails TO public
  2269. go
  2270. if object_id('MS_PerfDashboard.usp_TraceEventColumns', 'P') is not null
  2271. drop procedure MS_PerfDashboard.usp_TraceEventColumns
  2272. go
  2273. create procedure MS_PerfDashboard.usp_TraceEventColumns
  2274. as
  2275. begin
  2276. select trace_id,
  2277. status,
  2278. case when row_number = 1 then path else NULL end as path,
  2279. case when row_number = 1 then max_size else NULL end as max_size,
  2280. case when row_number = 1 then start_time else NULL end as start_time,
  2281. case when row_number = 1 then stop_time else NULL end as stop_time,
  2282. max_files,
  2283. is_rowset,
  2284. is_rollover,
  2285. is_shutdown,
  2286. is_default,
  2287. buffer_count,
  2288. buffer_size,
  2289. last_event_time,
  2290. event_count,
  2291. trace_event_id,
  2292. trace_event_name,
  2293. trace_column_id,
  2294. trace_column_name,
  2295. expensive_event
  2296. from
  2297. (SELECT t.id AS trace_id,
  2298. row_number() over (partition by t.id order by te.trace_event_id, tc.trace_column_id) as row_number,
  2299. t.status,
  2300. t.path,
  2301. t.max_size,
  2302. t.start_time,
  2303. t.stop_time,
  2304. t.max_files,
  2305. t.is_rowset,
  2306. t.is_rollover,
  2307. t.is_shutdown,
  2308. t.is_default,
  2309. t.buffer_count,
  2310. t.buffer_size,
  2311. t.last_event_time,
  2312. t.event_count,
  2313. te.trace_event_id,
  2314. te.name AS trace_event_name,
  2315. tc.trace_column_id,
  2316. tc.name AS trace_column_name,
  2317. case when te.trace_event_id in (23, 24, 40, 41, 44, 45, 51, 52, 54, 68, 96, 97, 98, 113, 114, 122, 146, 180) then cast(1 as bit) else cast(0 as bit) end as expensive_event
  2318. FROM sys.traces t
  2319. CROSS apply ::fn_trace_geteventinfo(t .id) AS e
  2320. JOIN sys.trace_events te ON te.trace_event_id = e.eventid
  2321. JOIN sys.trace_columns tc ON e.columnid = trace_column_id) as x
  2322. end
  2323. go
  2324. GRANT EXECUTE ON MS_PerfDashboard.usp_TraceEventColumns TO public
  2325. go
  2326. if object_id('MS_PerfDashboard.usp_Blocking', 'P') is not null
  2327. drop procedure MS_PerfDashboard.usp_Blocking
  2328. go
  2329. create procedure MS_PerfDashboard.usp_Blocking
  2330. as
  2331. begin
  2332. with blocking_hierarchy (head_wait_resource, session_id, blocking_session_id, tree_level, request_id, transaction_id,
  2333. status, sql_handle, plan_handle, statement_start_offset, statement_end_offset, wait_type, wait_time, wait_resource,
  2334. program_name, seconds_active_idle, open_transaction_count, transaction_isolation_level)
  2335. as
  2336. (
  2337. select
  2338. (select min(wait_resource) from sys.dm_exec_requests where blocking_session_id = s.session_id) as head_wait_resource,
  2339. s.session_id,
  2340. convert(smallint, NULL),
  2341. convert(int, 0),
  2342. r.request_id,
  2343. coalesce(r.transaction_id, st.transaction_id),
  2344. isnull(r.status, 'idle'),
  2345. r.sql_handle,
  2346. r.plan_handle,
  2347. r.statement_start_offset,
  2348. r.statement_end_offset,
  2349. r.wait_type,
  2350. r.wait_time,
  2351. r.wait_resource,
  2352. s.program_name,
  2353. case when r.request_id is null then datediff(ss, s.last_request_end_time, getdate()) else datediff(ss, r.start_time, getdate()) end,
  2354. convert(int, p.open_tran),
  2355. coalesce(r.transaction_isolation_level, s.transaction_isolation_level)
  2356. from sys.dm_exec_sessions s
  2357. join sys.sysprocesses p on s.session_id = p.spid
  2358. left join sys.dm_exec_requests r on s.session_id = r.session_id
  2359. left join sys.dm_tran_session_transactions st on s.session_id = st.session_id
  2360. where s.session_id in (select blocking_session_id from sys.dm_exec_requests)
  2361. and isnull(r.blocking_session_id, 0) = 0
  2362. union all
  2363. select b.head_wait_resource,
  2364. r.session_id,
  2365. r.blocking_session_id,
  2366. tree_level + 1,
  2367. r.request_id,
  2368. r.transaction_id,
  2369. r.status,
  2370. r.sql_handle,
  2371. r.plan_handle,
  2372. r.statement_start_offset,
  2373. r.statement_end_offset,
  2374. r.wait_type,
  2375. r.wait_time,
  2376. r.wait_resource,
  2377. NULL,
  2378. NULL,
  2379. r.open_transaction_count,
  2380. r.transaction_isolation_level
  2381. from sys.dm_exec_requests r
  2382. join blocking_hierarchy b on r.blocking_session_id = b.session_id
  2383. )
  2384. select b.head_wait_resource,
  2385. b.session_id,
  2386. b.request_id,
  2387. b.blocking_session_id,
  2388. b.program_name,
  2389. b.tree_level,
  2390. case when LEN(qt.query_text) < 2048 then qt.query_text else LEFT(qt.query_text, 2048) + N'...' end as query_text,
  2391. master.dbo.fn_varbintohexstr(b.sql_handle) as sql_handle,
  2392. master.dbo.fn_varbintohexstr(b.plan_handle) as plan_handle,
  2393. b.statement_start_offset,
  2394. b.statement_end_offset,
  2395. b.status as session_or_request_status,
  2396. b.wait_type,
  2397. b.wait_time,
  2398. b.wait_resource,
  2399. b.transaction_id,
  2400. b.transaction_isolation_level,
  2401. b.open_transaction_count,
  2402. b.seconds_active_idle,
  2403. t.name as transaction_name,
  2404. t.transaction_begin_time,
  2405. t.transaction_type,
  2406. t.transaction_state,
  2407. t.dtc_state,
  2408. t.dtc_isolation_level,
  2409. st.enlist_count,
  2410. st.is_user_transaction,
  2411. st.is_local,
  2412. st.is_enlisted,
  2413. st.is_bound
  2414. from blocking_hierarchy b
  2415. left join sys.dm_tran_session_transactions st on st.transaction_id = b.transaction_id and st.session_id = b.session_id
  2416. left join sys.dm_tran_active_transactions t on t.transaction_id = b.transaction_id
  2417. outer apply msdb.MS_PerfDashboard.fn_QueryTextFromHandle(b.sql_handle, b.statement_start_offset, b.statement_end_offset) as qt
  2418. end
  2419. go
  2420. GRANT EXECUTE ON MS_PerfDashboard.usp_Blocking TO public
  2421. go
  2422. if object_id('MS_PerfDashboard.usp_RequestIoWaits', 'P') is not null
  2423. drop procedure MS_PerfDashboard.usp_RequestIoWaits
  2424. go
  2425. create procedure MS_PerfDashboard.usp_RequestIoWaits @wait_type nvarchar(128)
  2426. as
  2427. begin
  2428. select
  2429. session_id,
  2430. request_id,
  2431. master.dbo.fn_varbintohexstr(sql_handle) as sql_handle,
  2432. master.dbo.fn_varbintohexstr(plan_handle) as plan_handle,
  2433. case when LEN(qt.query_text) < 2048 then qt.query_text else LEFT(qt.query_text, 2048) + N'...' end as query_text,
  2434. statement_start_offset,
  2435. statement_end_offset,
  2436. wait_type,
  2437. wait_time,
  2438. wait_resource,
  2439. blocking_session_id
  2440. from sys.dm_exec_requests r
  2441. outer apply msdb.MS_PerfDashboard.fn_QueryTextFromHandle(sql_handle, statement_start_offset, statement_end_offset) as qt
  2442. where msdb.MS_PerfDashboard.fn_WaitTypeCategory(wait_type) = @wait_type --N'Buffer IO'/N'Buffer Latch'
  2443. end
  2444. go
  2445. GRANT EXECUTE ON MS_PerfDashboard.usp_RequestIoWaits TO public
  2446. go
  2447. if object_id('MS_PerfDashboard.usp_LargestIoRequests', 'P') is not null
  2448. drop procedure MS_PerfDashboard.usp_LargestIoRequests
  2449. go
  2450. create procedure MS_PerfDashboard.usp_LargestIoRequests
  2451. as
  2452. begin
  2453. select top 20
  2454. r.session_id,
  2455. r.request_id,
  2456. master.dbo.fn_varbintohexstr(sql_handle) as sql_handle,
  2457. master.dbo.fn_varbintohexstr(plan_handle) as plan_handle,
  2458. case when LEN(qt.query_text) < 2048 then qt.query_text else LEFT(qt.query_text, 2048) + N'...' end as query_text,
  2459. r.statement_start_offset,
  2460. r.statement_end_offset,
  2461. r.logical_reads,
  2462. r.reads,
  2463. r.writes,
  2464. r.wait_type,
  2465. r.wait_time,
  2466. r.wait_resource,
  2467. r.blocking_session_id,
  2468. case when r.logical_reads > 0 then (r.logical_reads - isnull(r.reads, 0)) / convert(float, r.logical_reads)
  2469. else NULL
  2470. end as cache_hit_ratio
  2471. from sys.dm_exec_requests r
  2472. join sys.dm_exec_sessions s on r.session_id = s.session_id
  2473. outer apply msdb.MS_PerfDashboard.fn_QueryTextFromHandle(r.sql_handle, r.statement_start_offset, r.statement_end_offset) as qt
  2474. where s.is_user_process = 0x1 and (r.reads > 0 or r.writes > 0)
  2475. order by (r.reads + r.writes) desc
  2476. end
  2477. go
  2478. GRANT EXECUTE ON MS_PerfDashboard.usp_LargestIoRequests TO public
  2479. go
  2480. if object_id('MS_PerfDashboard.usp_RequestWaits', 'P') is not null
  2481. drop procedure MS_PerfDashboard.usp_RequestWaits
  2482. go
  2483. create procedure MS_PerfDashboard.usp_RequestWaits
  2484. as
  2485. begin
  2486. select r.session_id,
  2487. r.request_id,
  2488. master.dbo.fn_varbintohexstr(r.sql_handle) as sql_handle,
  2489. master.dbo.fn_varbintohexstr(r.plan_handle) as plan_handle,
  2490. case when LEN(qt.query_text) < 2048 then qt.query_text else LEFT(qt.query_text, 2048) + N'...' end as query_text,
  2491. r.statement_start_offset,
  2492. r.statement_end_offset,
  2493. r.wait_time,
  2494. r.wait_type,
  2495. r.wait_resource,
  2496. msdb.MS_PerfDashboard.fn_WaitTypeCategory(wait_type) as wait_category
  2497. from sys.dm_exec_requests r
  2498. join sys.dm_exec_sessions s on r.session_id = s.session_id
  2499. outer apply msdb.MS_PerfDashboard.fn_QueryTextFromHandle(r.sql_handle, r.statement_start_offset, r.statement_end_offset) as qt
  2500. where r.wait_type is not null and s.is_user_process = 0x1
  2501. end
  2502. go
  2503. GRANT EXECUTE ON MS_PerfDashboard.usp_RequestWaits TO public
  2504. go
  2505. if object_id('MS_PerfDashboard.usp_LatchStats', 'P') is not null
  2506. drop procedure MS_PerfDashboard.usp_LatchStats
  2507. go
  2508. create procedure MS_PerfDashboard.usp_LatchStats
  2509. as
  2510. begin
  2511. select
  2512. latch_class,
  2513. waiting_requests_count,
  2514. wait_time_ms,
  2515. max_wait_time_ms
  2516. from sys.dm_os_latch_stats
  2517. where waiting_requests_count > 0
  2518. end
  2519. go
  2520. GRANT EXECUTE ON MS_PerfDashboard.usp_LatchStats TO public
  2521. go
  2522. if object_id('MS_PerfDashboard.usp_RequestsWithLatchWaits', 'P') is not null
  2523. drop procedure MS_PerfDashboard.usp_RequestsWithLatchWaits
  2524. go
  2525. create procedure MS_PerfDashboard.usp_RequestsWithLatchWaits
  2526. as
  2527. begin
  2528. select
  2529. r.session_id,
  2530. r.request_id,
  2531. master.dbo.fn_varbintohexstr(r.sql_handle) as sql_handle,
  2532. master.dbo.fn_varbintohexstr(r.plan_handle) as plan_handle,
  2533. case when LEN(qt.query_text) < 2048 then qt.query_text else LEFT(qt.query_text, 2048) + N'...' end as query_text,
  2534. r.statement_start_offset,
  2535. r.statement_end_offset,
  2536. r.wait_type,
  2537. r.wait_time,
  2538. r.wait_resource
  2539. from sys.dm_exec_requests r
  2540. outer apply msdb.MS_PerfDashboard.fn_QueryTextFromHandle(r.sql_handle, r.statement_start_offset, r.statement_end_offset) as qt
  2541. where msdb.MS_PerfDashboard.fn_WaitTypeCategory(wait_type) = 'Latch'
  2542. end
  2543. go
  2544. GRANT EXECUTE ON MS_PerfDashboard.usp_RequestsWithLatchWaits TO public
  2545. go
  2546. if object_id('MS_PerfDashboard.usp_XEventSessions', 'P') is not null
  2547. drop procedure MS_PerfDashboard.usp_XEventSessions
  2548. go
  2549. create procedure MS_PerfDashboard.usp_XEventSessions
  2550. as
  2551. begin
  2552. select convert(bigint, address) xeaddress,
  2553. case when row_num = 1 then session_name else NULL end as session_name,
  2554. case when row_num = 1 then create_time else NULL end as create_time,
  2555. case when row_num = 1 then target_name else NULL end as target_name,
  2556. case when row_num = 1 then execution_count else NULL end as execution_count,
  2557. case when row_num = 1 then execution_duration_ms else NULL end as execution_duration_ms,
  2558. case when row_num = 1 then dropped_event_count else NULL end as dropped_event_count,
  2559. case when row_num = 1 then buffer_policy_desc else NULL end as buffer_policy_desc,
  2560. case when row_num = 1 then total_buffer_size else NULL end as total_buffer_size,
  2561. event_name,
  2562. action_name
  2563. from (
  2564. select s.address, ROW_NUMBER() over (partition by s.address order by sea.event_name, sea.action_name ) as row_num,
  2565. s.name session_name ,s.create_time, st.target_name, st.execution_count, st.execution_duration_ms,
  2566. sea.action_name, sea.event_name, s.dropped_event_count, s.total_buffer_size, s.buffer_policy_desc
  2567. from sys.dm_xe_sessions s
  2568. inner join sys.dm_xe_session_targets st
  2569. on s.address = st.event_session_address
  2570. inner join sys.dm_xe_session_event_actions sea
  2571. on s.address = sea.event_session_address ) as inner_t
  2572. end
  2573. go
  2574. GRANT EXECUTE ON MS_PerfDashboard.usp_XEventSessions TO public
  2575. go
  2576. if object_id('MS_PerfDashboard.usp_QueryStatsDetails ', 'P') is not null
  2577. drop procedure MS_PerfDashboard.usp_QueryStatsDetails
  2578. go
  2579. create procedure MS_PerfDashboard.usp_QueryStatsDetails @query_hash varchar(64), @OrderBy_Criteria nvarchar(128)
  2580. as
  2581. begin
  2582. select TOP 50
  2583. db_name(qt.database_id) as database_name,
  2584. qt.query_text,
  2585. qt.encrypted,
  2586. creation_time,
  2587. last_execution_time,
  2588. execution_count,
  2589. plan_generation_num,
  2590. total_worker_time,
  2591. last_worker_time,
  2592. min_worker_time,
  2593. max_worker_time,
  2594. total_physical_reads,
  2595. last_physical_reads,
  2596. min_physical_reads,
  2597. max_physical_reads,
  2598. total_logical_reads,
  2599. last_logical_reads,
  2600. min_logical_reads,
  2601. max_logical_reads,
  2602. total_logical_writes,
  2603. last_logical_writes,
  2604. min_logical_writes,
  2605. max_logical_writes,
  2606. total_clr_time,
  2607. last_clr_time,
  2608. min_clr_time,
  2609. max_clr_time,
  2610. total_elapsed_time,
  2611. last_elapsed_time,
  2612. min_elapsed_time,
  2613. max_elapsed_time,
  2614. master.dbo.fn_varbintohexstr(sql_handle) as sql_handle,
  2615. master.dbo.fn_varbintohexstr(plan_handle) as plan_handle,
  2616. statement_start_offset,
  2617. statement_end_offset,
  2618. CASE @OrderBy_Criteria
  2619. WHEN 'Logical Reads' THEN total_logical_reads
  2620. WHEN 'Physical Reads' THEN total_physical_reads
  2621. WHEN 'Logical Writes' THEN total_logical_writes
  2622. WHEN 'CPU' THEN total_worker_time / 1000
  2623. WHEN 'Duration' THEN total_elapsed_time / 1000
  2624. WHEN 'CLR Time' THEN total_clr_time/ 1000
  2625. END as sort_value
  2626. from sys.dm_exec_query_stats qs
  2627. cross apply msdb.MS_PerfDashboard.fn_QueryTextFromHandle(sql_handle, statement_start_offset, statement_end_offset) qt
  2628. where query_hash = MS_PerfDashboard.fn_hexstrtovarbin(@query_hash)
  2629. order by sort_value desc
  2630. end
  2631. go
  2632. GRANT EXECUTE ON MS_PerfDashboard.usp_QueryStatsDetails TO public
  2633. go
  2634. PRINT 'Script completed!';
  2635. go