@@ -1564,10 +1564,10 @@ database_id INT
15641564
15651565CREATE TABLE #plan_usage
15661566(
1567- duplicate_plan_handles BIGINT NULL ,
1568- percent_duplicate NUMERIC ( 7 , 2 ) NULL ,
1567+ duplicate_plan_hashes BIGINT NULL ,
1568+ percent_duplicate DECIMAL ( 5 , 2 ) NULL ,
15691569 single_use_plan_count BIGINT NULL ,
1570- percent_single NUMERIC ( 7 , 2 ) NULL ,
1570+ percent_single DECIMAL ( 5 , 2 ) NULL ,
15711571 total_plans BIGINT NULL ,
15721572 spid INT
15731573);
@@ -1601,49 +1601,90 @@ OPTION (RECOMPILE);
16011601RAISERROR (N ' Checking for single use plans and plans with many queries' , 0 , 1 ) WITH NOWAIT ;
16021602WITH total_plans AS
16031603(
1604- SELECT COUNT_BIG ( * ) AS total_plans
1605- FROM sys . dm_exec_cached_plans AS deqs
1606- WHERE deqs . cacheobjtype = N ' Compiled Plan'
1604+ SELECT
1605+ COUNT_BIG ( deqs . query_plan_hash ) AS total_plans
1606+ FROM sys . dm_exec_query_stats AS deqs
16071607),
16081608 many_plans AS
16091609(
1610- SELECT SUM (x .duplicate_plan_handles ) AS duplicate_plan_handles
1611- FROM (
1612- SELECT COUNT_BIG (DISTINCT plan_handle) AS duplicate_plan_handles
1610+ SELECT
1611+ SUM (x .duplicate_plan_hashes ) AS duplicate_plan_hashes
1612+ FROM
1613+ (
1614+ SELECT
1615+ COUNT_BIG (qs .query_plan_hash ) AS duplicate_plan_hashes
16131616 FROM sys .dm_exec_query_stats qs
1614- CROSS APPLY sys .dm_exec_plan_attributes (qs .plan_handle ) pa
1617+ LEFT JOIN sys .dm_exec_procedure_stats ps
1618+ ON qs .sql_handle = ps .sql_handle
1619+ CROSS APPLY sys .dm_exec_plan_attributes (qs .plan_handle ) pa
16151620 WHERE pa .attribute = N ' dbid'
1616- GROUP BY qs .query_hash , pa .value
1617- HAVING COUNT_BIG (DISTINCT plan_handle) > 5
1621+ AND qs .query_plan_hash <> 0x0000000000000000
1622+ GROUP BY
1623+ /* qs.query_plan_hash, BGO 20210524 commenting this out to fix #2909 */
1624+ qs .query_hash ,
1625+ ps .object_id ,
1626+ pa .value
1627+ HAVING COUNT_BIG (qs .query_plan_hash ) > 5
16181628 ) AS x
16191629),
16201630 single_use_plans AS
16211631(
1622- SELECT COUNT_BIG (* ) AS single_use_plan_count
1632+ SELECT
1633+ COUNT_BIG (* ) AS single_use_plan_count
16231634 FROM sys .dm_exec_cached_plans AS cp
16241635 WHERE cp .usecounts = 1
16251636 AND cp .objtype = N ' Adhoc'
1626- AND EXISTS ( SELECT 1 / 0
1627- FROM sys .configurations AS c
1628- WHERE c .name = N ' optimize for ad hoc workloads'
1629- AND c .value_in_use = 0 )
1637+ AND EXISTS
1638+ (
1639+ SELECT
1640+ 1 / 0
1641+ FROM sys .configurations AS c
1642+ WHERE c .name = N ' optimize for ad hoc workloads'
1643+ AND c .value_in_use = 0
1644+ )
16301645 HAVING COUNT_BIG (* ) > 1
16311646)
1632- INSERT #plan_usage ( duplicate_plan_handles, percent_duplicate, single_use_plan_count, percent_single, total_plans, spid )
1633- SELECT m .duplicate_plan_handles ,
1634- CONVERT (DECIMAL (5 ,2 ), m .duplicate_plan_handles / (1 . * NULLIF (t .total_plans , 0 ))) * 100 . AS percent_duplicate,
1635- s .single_use_plan_count ,
1636- CONVERT (DECIMAL (5 ,2 ), s .single_use_plan_count / (1 . * NULLIF (t .total_plans , 0 ))) * 100 . AS percent_single,
1637- t .total_plans ,
1638- @@SPID
1639- FROM many_plans AS m
1640- CROSS APPLY single_use_plans AS s
1641- CROSS APPLY total_plans AS t;
1647+ INSERT
1648+ #plan_usage
1649+ (
1650+ duplicate_plan_hashes,
1651+ percent_duplicate,
1652+ single_use_plan_count,
1653+ percent_single,
1654+ total_plans,
1655+ spid
1656+ )
1657+ SELECT
1658+ m .duplicate_plan_hashes ,
1659+ CONVERT
1660+ (
1661+ decimal (5 ,2 ),
1662+ m .duplicate_plan_hashes
1663+ / (1 . * NULLIF (t .total_plans , 0 ))
1664+ ) * 100 . AS percent_duplicate,
1665+ s .single_use_plan_count ,
1666+ CONVERT
1667+ (
1668+ decimal (5 ,2 ),
1669+ s .single_use_plan_count
1670+ / (1 . * NULLIF (t .total_plans , 0 ))
1671+ ) * 100 . AS percent_single,
1672+ t .total_plans ,
1673+ @@SPID
1674+ FROM many_plans AS m
1675+ CROSS JOIN single_use_plans AS s
1676+ CROSS JOIN total_plans AS t;
16421677
16431678
1679+ /*
1680+ Erik Darling:
1681+ Quoting this out to see if the above query fixes the issue
1682+ 2021-05-17, Issue #2909
1683+
16441684UPDATE #plan_usage
16451685 SET percent_duplicate = CASE WHEN percent_duplicate > 100 THEN 100 ELSE percent_duplicate END,
16461686 percent_single = CASE WHEN percent_duplicate > 100 THEN 100 ELSE percent_duplicate END;
1687+ */
16471688
16481689SET @OnlySqlHandles = LTRIM (RTRIM (@OnlySqlHandles)) ;
16491690SET @OnlyQueryHashes = LTRIM (RTRIM (@OnlyQueryHashes)) ;
0 commit comments