Skip to main content

Case study of SQL Server plan guide with SQL and Procedure

A application run a query which sometimes slow on one literal but fast on the other, this is the case study of SQL Server plan guide feature:

Slow query: use 255 as literal, run duration is ~ 1 minute

SELECT top 1 mh.intnum as intnum,rh.remark as remark,reportid FROM msghead mh inner join msgdetail md on md.intnum = mh.msgintnum left outer join rephistory rh on md.functionnum = 45000 AND md.functionref = rh.intnum WHERE readon < '1900/01/02' AND((isnull(rh.userid,0) = 255 AND md.functionnum = 45000 and rh.remark like 'http%')) 

Fast query: use 167 or 66 as literal, complete in less than 1 second

SELECT top 1 mh.intnum as intnum,rh.remark as remark,reportid FROM msghead mh inner join msgdetail md on md.intnum = mh.msgintnum left outer join rephistory rh on md.functionnum = 45000 AND md.functionref = rh.intnum WHERE readon < '1900/01/02' AND((isnull(rh.userid,0) = 167 AND md.functionnum = 45000 and rh.remark like 'http%')) 

Thanks to this book: outlined the steps to implement

https://books.google.ca/books?id=wK1CAwAAQBAJ&pg=PT1200&lpg=PT1200&dq=sql+server+plan+guide+template+literal+SHOWPLAN_XML&source=bl&ots=iuIR6SzIE5&sig=ACfU3U1bTbUwofgeFoYGFC0TX2CEzeA2CQ&hl=en&sa=X&ved=2ahUKEwi1qvXN0bbzAhX3IjQIHcc_D1wQ6AF6BAgVEAM#v=onepage&q=sql%20server%20plan%20guide%20template%20literal%20SHOWPLAN_XML&f=false

Here are the steps:

DECLARE @my_templatetext nvarchar(max)  

DECLARE @my_parameters nvarchar(max)  

EXEC sp_get_query_template   

    N'SELECT top 1 mh.intnum as intnum,rh.remark as remark,reportid FROM msghead mh 

inner join msgdetail md on md.intnum = mh.msgintnum 

left outer join rephistory rh on md.functionnum = 45000 AND md.functionref = rh.intnum WHERE readon < ''1900/01/02'' 

AND((isnull(rh.userid,0) = 167 AND md.functionnum = 45000 and rh.remark like ''http%''))',  

@my_templatetext OUTPUT,  

@my_parameters OUTPUT;  

SELECT @my_templatetext;  

SELECT @my_parameters; 


exec sp_create_plan_guide

@name=N'plan_guide_template_plan_for_select_top_1_blabla',

@stmt = @my_templatetext,

@type = N'TEMPLATE',

@module_or_batch=null,

@params=@my_parameters,

@hints=N'OPTION (PARAMETERIZATION FORCED)';


exec sp_create_plan_guide

@name=N'plan_guide_for_select_top_1_blabla',

@stmt = @my_templatetext,

@type = N'SQL',

@module_or_batch=null,

@params=@my_parameters,

@hints=N'OPTION (OPTIMIZE FOR (@3=167))';

Comparing the plan, the plan guide is being used.


The query is parameterized, and both template and SQL plan guides are applied.

(@0 int,@1 varchar(8000),@2 int,@3 int,@4 int)select top 1 mh . intnum as intnum , rh . remark as remark , reportid from msghead mh inner join msgdetail md on md . intnum = mh . msgintnum left outer join rephistory rh on md . functionnum = @0 and md . functionref = rh . intnum where readon < @1 and ( ( isnull ( rh . userid , @2 ) = @3 and md . functionnum = @4 and rh . remark like 'http%' ) )

But the performance is still bad! so this plan is not helping literal 255, let me try optimize the plan for another literal 66. 

 EXEC sp_control_plan_guide N'DROP', N'plan_guide_for_select_top_1_blabla' 

exec sp_create_plan_guide

@name=N'plan_guide_for_select_top_1_blabla',

@stmt = @my_templatetext,

@type = N'SQL',

@module_or_batch=null,

@params=@my_parameters,

@hints=N'OPTION (OPTIMIZE FOR (@3=66))';

This one works! all literal complete in less than 1 second by using the plan guide.

Tested performance for literal tried : 255, 261,271,167,66, they all completed in 1 second.



SELECT plan_guide_id, msgnum, severity, state, message  

FROM sys.plan_guides  

CROSS APPLY fn_validate_plan_guide(plan_guide_id);  

GO  

select * from sys.plan_guides  


Now, what about if a query is run in a procedure which use parameter/variable? can we still guide the plan?

Thanks to this link below, let's give it a try:
https://dbtut.com/index.php/2019/05/09/increase-query-performance-in-sql-server-using-sp_create_plan_guide-system-stored-procedure/

The two cases below indicates either all literal or combination of literal and parameter both work:

For the all parameters:

CREATE PROCEDURE dbo.jsun( @userid INT,@readondate date,@remark varchar(99),@num int)
AS
select @remark='http%'
select @num=45000
SELECT top 1 mh.intnum as intnum,rh.remark as remark,reportid 
FROM msghead mh inner 
join msgdetail md on md.intnum = mh.msgintnum 
left outer join rephistory rh on md.functionnum = @num AND md.functionref = rh.intnum 
WHERE readon < @readondate AND((isnull(rh.userid,0) = @userid AND md.functionnum = @num and rh.remark like  @remark))

EXEC sp_control_plan_guide N'DROP', N'plan_guide_jsun' 

exec sp_create_plan_guide
@name=N'plan_guide_jsun',
@stmt = N'SELECT top 1 mh.intnum as intnum,rh.remark as remark,reportid 
FROM msghead mh inner 
join msgdetail md on md.intnum = mh.msgintnum 
left outer join rephistory rh on md.functionnum = @num AND md.functionref = rh.intnum 
WHERE readon < @readondate AND((isnull(rh.userid,0) = @userid AND md.functionnum = @num and rh.remark like  @remark))',
@type = N'OBJECT',
@module_or_batch=N'dbo.jsun',
@params=NULL,
@hints=N'OPTION (OPTIMIZE FOR (@userid=66))';

for Combination of literal (45000) and parameter (@userid):

drop procedure dbo.jsun
go
CREATE PROCEDURE dbo.jsun( @userid INT)
AS
SELECT top 1 mh.intnum as intnum,rh.remark as remark,reportid 
FROM msghead mh inner join msgdetail md on md.intnum = mh.msgintnum 
left outer join rephistory rh on md.functionnum = 45000 AND md.functionref = rh.intnum 
WHERE readon < '1900/01/02' AND((isnull(rh.userid,0) = @userid AND md.functionnum = 45000 and rh.remark like 'http%'))

exec sp_create_plan_guide
@name=N'plan_guide_jsun',
@stmt = N'
SELECT top 1 mh.intnum as intnum,rh.remark as remark,reportid 
FROM msghead mh inner join msgdetail md on md.intnum = mh.msgintnum 
left outer join rephistory rh on md.functionnum = 45000 AND md.functionref = rh.intnum 
WHERE readon < ''1900/01/02'' AND((isnull(rh.userid,0) = @userid AND md.functionnum = 45000 and rh.remark like ''http%''))',
@type = N'OBJECT',
@module_or_batch=N'dbo.jsun',
@params=NULL,
@hints=N'OPTION (OPTIMIZE FOR (@userid=66))';

The @stmt has to match the proc sql, for example, if you change 1900 to 1901, then, you will get error like:
Msg 10507, Level 16, State 1, Procedure jsun, Line 1 [Batch Start Line 54]
Cannot create plan guide 'plan_guide_jsun' because the statement specified by @stmt and @module_or_batch, or by @plan_handle and @statement_start_offset, does not match any statement in the specified module or batch. Modify the values to match a statement in the module or batch.

Compare the plan and it's working.

Now, one more question: Can I guide the slow query (literal 255) with a plan generated by faster query(literal 66)?
Yes, I can use option (use plan N '<ShowPlanXML...' )

The XML plan come from the fast query literal, it's like this:

SELECT top 1 mh.intnum as intnum,rh.remark as remark,reportid FROM msghead mh inner join msgdetail md on md.intnum = mh.msgintnum left outer join rephistory rh on md.functionnum = 45000 AND md.functionref = rh.intnum WHERE readon < '1900/01/02' AND((isnull(rh.userid,0) = 255 AND md.functionnum = 45000 and rh.remark like 'http%'))
OPTION (
USE PLAN N'
<ShowPlanXML xmlns="http://schemas.microsoft.com/sqlserver/2004/07/showplan" Version="1.2" Build="11.0.5388.0">
  <BatchSequence>
    <Batch>
      <Statements>
        <StmtSimple StatementText="SELECT top 1 mh.intnum as intnum,rh.remark as remark,reportid FROM msghead mh inner join msgdetail md on md.intnum = mh.msgintnum left outer join rephistory rh on md.functionnum = 45000 AND md.functionref = rh.intnum WHERE readon &lt; ''1900/01/02'' AND((isnull(rh.userid,0) = 66 AND md.functionnum = 45000 and rh.remark like ''http%''))" StatementId="1" StatementCompId="1" StatementType="SELECT" RetrievedFromCache="true" TemplatePlanGuideDB="EatecX" TemplatePlanGuideName="plan_guide_template_plan_for_select_top_1_blabla" PlanGuideDB="EatecX" PlanGuideName="plan_guide_for_select_top_1_blabla" StatementSubTreeCost="0.136546" StatementEstRows="1" StatementOptmLevel="FULL" QueryHash="0x141148985EA2FDC3" QueryPlanHash="0x57121A5A45AFC5F3" StatementOptmEarlyAbortReason="GoodEnoughPlanFound" ParameterizedText="(@0 int,@1 varchar(8000),@2 int,@3 int,@4 int)select top 1 mh . intnum as intnum , rh . remark as remark , reportid from msghead mh inner join msgdetail md on md . intnum = mh . msgintnum left outer join rephistory rh on md . functionnum = @0 and md . functionref = rh . intnum where readon &lt; @1 and ( ( isnull ( rh . userid , @2 ) = @3 and md . functionnum = @4 and rh . remark like ''http%'' ) )">
          <StatementSetOptions QUOTED_IDENTIFIER="true" ARITHABORT="true" CONCAT_NULL_YIELDS_NULL="true" ANSI_NULLS="true" ANSI_PADDING="true" ANSI_WARNINGS="true" NUMERIC_ROUNDABORT="false" />
          <QueryPlan CachedPlanSize="72" CompileTime="10" CompileCPU="10" CompileMemory="856">
            <MemoryGrantInfo SerialRequiredMemory="1024" SerialDesiredMemory="20992" />
            <OptimizerHardwareDependentProperties EstimatedAvailableMemoryGrant="419407" EstimatedPagesCached="52425" EstimatedAvailableDegreeOfParallelism="2" />
            <RelOp NodeId="0" PhysicalOp="Top" LogicalOp="Top" EstimateRows="1" EstimateIO="0" EstimateCPU="1e-007" AvgRowSize="95" EstimatedTotalSubtreeCost="0.136546" Parallel="0" EstimateRebinds="0" EstimateRewinds="0" EstimatedExecutionMode="Row">
              <OutputList>
                <ColumnReference Database="[EatecX]" Schema="[dbo]" Table="[msghead]" Alias="[mh]" Column="intnum" />
                <ColumnReference Database="[EatecX]" Schema="[dbo]" Table="[rephistory]" Alias="[rh]" Column="reportid" />
                <ColumnReference Database="[EatecX]" Schema="[dbo]" Table="[rephistory]" Alias="[rh]" Column="remark" />
              </OutputList>
              <Top RowCount="0" IsPercent="0" WithTies="0">
                <TopExpression>
                  <ScalarOperator ScalarString="(1)">
                    <Const ConstValue="(1)" />
                  </ScalarOperator>
                </TopExpression>
                <RelOp NodeId="1" PhysicalOp="Nested Loops" LogicalOp="Inner Join" EstimateRows="1.00046" EstimateIO="0" EstimateCPU="0.0151884" AvgRowSize="103" EstimatedTotalSubtreeCost="0.136546" Parallel="0" EstimateRebinds="0" EstimateRewinds="0" EstimatedExecutionMode="Row">
                  <OutputList>
                    <ColumnReference Database="[EatecX]" Schema="[dbo]" Table="[msghead]" Alias="[mh]" Column="intnum" />
                    <ColumnReference Database="[EatecX]" Schema="[dbo]" Table="[rephistory]" Alias="[rh]" Column="reportid" />
                    <ColumnReference Database="[EatecX]" Schema="[dbo]" Table="[rephistory]" Alias="[rh]" Column="remark" />
                  </OutputList>
                  <NestedLoops Optimized="0" WithUnorderedPrefetch="1">
                    <OuterReferences>
                      <ColumnReference Database="[EatecX]" Schema="[dbo]" Table="[msghead]" Alias="[mh]" Column="intnum" />
                      <ColumnReference Column="Expr1012" />
                    </OuterReferences>
                    <RelOp NodeId="3" PhysicalOp="Nested Loops" LogicalOp="Inner Join" EstimateRows="1.00046" EstimateIO="0" EstimateCPU="0.0236158" AvgRowSize="95" EstimatedTotalSubtreeCost="0.129981" Parallel="0" EstimateRebinds="0" EstimateRewinds="0" EstimatedExecutionMode="Row">
                      <OutputList>
                        <ColumnReference Database="[EatecX]" Schema="[dbo]" Table="[msghead]" Alias="[mh]" Column="intnum" />
                        <ColumnReference Database="[EatecX]" Schema="[dbo]" Table="[rephistory]" Alias="[rh]" Column="reportid" />
                        <ColumnReference Database="[EatecX]" Schema="[dbo]" Table="[rephistory]" Alias="[rh]" Column="remark" />
                      </OutputList>
                      <NestedLoops Optimized="0" WithUnorderedPrefetch="1">
                        <OuterReferences>
                          <ColumnReference Database="[EatecX]" Schema="[dbo]" Table="[msgdetail]" Alias="[md]" Column="intnum" />
                          <ColumnReference Column="Expr1011" />
                        </OuterReferences>
                        <RelOp NodeId="5" PhysicalOp="Nested Loops" LogicalOp="Inner Join" EstimateRows="13.5787" EstimateIO="0" EstimateCPU="0.206144" AvgRowSize="99" EstimatedTotalSubtreeCost="0.121599" Parallel="0" EstimateRebinds="0" EstimateRewinds="0" EstimatedExecutionMode="Row">
                          <OutputList>
                            <ColumnReference Database="[EatecX]" Schema="[dbo]" Table="[msgdetail]" Alias="[md]" Column="intnum" />
                            <ColumnReference Database="[EatecX]" Schema="[dbo]" Table="[rephistory]" Alias="[rh]" Column="reportid" />
                            <ColumnReference Database="[EatecX]" Schema="[dbo]" Table="[rephistory]" Alias="[rh]" Column="remark" />
                          </OutputList>
                          <NestedLoops Optimized="1" WithUnorderedPrefetch="1">
                            <OuterReferences>
                              <ColumnReference Column="Bmk1004" />
                              <ColumnReference Column="Expr1010" />
                            </OuterReferences>
                            <RelOp NodeId="8" PhysicalOp="Compute Scalar" LogicalOp="Compute Scalar" EstimateRows="13.5787" EstimateIO="0" EstimateCPU="0.309376" AvgRowSize="19" EstimatedTotalSubtreeCost="0.0736979" Parallel="0" EstimateRebinds="0" EstimateRewinds="0" EstimatedExecutionMode="Row">
                              <OutputList>
                                <ColumnReference Database="[EatecX]" Schema="[dbo]" Table="[msgdetail]" Alias="[md]" Column="intnum" />
                                <ColumnReference Column="Bmk1004" />
                                <ColumnReference Column="Expr1009" />
                              </OutputList>
                              <ComputeScalar>
                                <DefinedValues>
                                  <DefinedValue>
                                    <ColumnReference Column="Expr1009" />
                                    <ScalarOperator ScalarString="BmkToPage([Bmk1004])">
                                      <Intrinsic FunctionName="BmkToPage">
                                        <ScalarOperator>
                                          <Identifier>
                                            <ColumnReference Column="Bmk1004" />
                                          </Identifier>
                                        </ScalarOperator>
                                      </Intrinsic>
                                    </ScalarOperator>
                                  </DefinedValue>
                                </DefinedValues>
                                <RelOp NodeId="9" PhysicalOp="Nested Loops" LogicalOp="Inner Join" EstimateRows="13.5787" EstimateIO="0" EstimateCPU="0.309376" AvgRowSize="19" EstimatedTotalSubtreeCost="0.0736979" Parallel="0" EstimateRebinds="0" EstimateRewinds="0" EstimatedExecutionMode="Row">
                                  <OutputList>
                                    <ColumnReference Database="[EatecX]" Schema="[dbo]" Table="[msgdetail]" Alias="[md]" Column="intnum" />
                                    <ColumnReference Column="Bmk1004" />
                                  </OutputList>
                                  <NestedLoops Optimized="1" WithUnorderedPrefetch="1">
                                    <OuterReferences>
                                      <ColumnReference Database="[EatecX]" Schema="[dbo]" Table="[msgdetail]" Alias="[md]" Column="functionref" />
                                      <ColumnReference Column="Expr1008" />
                                    </OuterReferences>
                                    <RelOp NodeId="12" PhysicalOp="Clustered Index Scan" LogicalOp="Clustered Index Scan" EstimateRows="20.3786" EstimateIO="2.82905" EstimateCPU="0.217243" AvgRowSize="19" EstimatedTotalSubtreeCost="0.00410554" TableCardinality="197351" Parallel="0" EstimateRebinds="0" EstimateRewinds="0" EstimatedExecutionMode="Row">
                                      <OutputList>
                                        <ColumnReference Database="[EatecX]" Schema="[dbo]" Table="[msgdetail]" Alias="[md]" Column="intnum" />
                                        <ColumnReference Database="[EatecX]" Schema="[dbo]" Table="[msgdetail]" Alias="[md]" Column="functionref" />
                                      </OutputList>
                                      <IndexScan Ordered="0" ForcedIndex="0" ForceScan="0" NoExpandHint="0">
                                        <DefinedValues>
                                          <DefinedValue>
                                            <ColumnReference Database="[EatecX]" Schema="[dbo]" Table="[msgdetail]" Alias="[md]" Column="intnum" />
                                          </DefinedValue>
                                          <DefinedValue>
                                            <ColumnReference Database="[EatecX]" Schema="[dbo]" Table="[msgdetail]" Alias="[md]" Column="functionref" />
                                          </DefinedValue>
                                        </DefinedValues>
                                        <Object Database="[EatecX]" Schema="[dbo]" Table="[msgdetail]" Index="[PK_msgdetail]" Alias="[md]" IndexKind="Clustered" />
                                        <Predicate>
                                          <ScalarOperator ScalarString="[EatecX].[dbo].[msgdetail].[functionnum] as [md].[functionnum]=[@0] AND [EatecX].[dbo].[msgdetail].[functionnum] as [md].[functionnum]=[@4]">
                                            <Logical Operation="AND">
                                              <ScalarOperator>
                                                <Compare CompareOp="EQ">
                                                  <ScalarOperator>
                                                    <Identifier>
                                                      <ColumnReference Database="[EatecX]" Schema="[dbo]" Table="[msgdetail]" Alias="[md]" Column="functionnum" />
                                                    </Identifier>
                                                  </ScalarOperator>
                                                  <ScalarOperator>
                                                    <Identifier>
                                                      <ColumnReference Column="@0" />
                                                    </Identifier>
                                                  </ScalarOperator>
                                                </Compare>
                                              </ScalarOperator>
                                              <ScalarOperator>
                                                <Compare CompareOp="EQ">
                                                  <ScalarOperator>
                                                    <Identifier>
                                                      <ColumnReference Database="[EatecX]" Schema="[dbo]" Table="[msgdetail]" Alias="[md]" Column="functionnum" />
                                                    </Identifier>
                                                  </ScalarOperator>
                                                  <ScalarOperator>
                                                    <Identifier>
                                                      <ColumnReference Column="@4" />
                                                    </Identifier>
                                                  </ScalarOperator>
                                                </Compare>
                                              </ScalarOperator>
                                            </Logical>
                                          </ScalarOperator>
                                        </Predicate>
                                      </IndexScan>
                                    </RelOp>
                                    <RelOp NodeId="13" PhysicalOp="Index Seek" LogicalOp="Index Seek" EstimateRows="1" EstimateIO="0.003125" EstimateCPU="0.0001581" AvgRowSize="15" EstimatedTotalSubtreeCost="0.0919986" TableCardinality="1.42545e+006" Parallel="0" EstimateRebinds="27.1575" EstimateRewinds="0.12225" EstimatedExecutionMode="Row">
                                      <OutputList>
                                        <ColumnReference Column="Bmk1004" />
                                      </OutputList>
                                      <IndexScan Ordered="1" ScanDirection="FORWARD" ForcedIndex="0" ForceSeek="0" ForceScan="0" NoExpandHint="0" Storage="RowStore">
                                        <DefinedValues>
                                          <DefinedValue>
                                            <ColumnReference Column="Bmk1004" />
                                          </DefinedValue>
                                        </DefinedValues>
                                        <Object Database="[EatecX]" Schema="[dbo]" Table="[rephistory]" Index="[reph_pk]" Alias="[rh]" IndexKind="NonClustered" />
                                        <SeekPredicates>
                                          <SeekPredicateNew>
                                            <SeekKeys>
                                              <Prefix ScanType="EQ">
                                                <RangeColumns>
                                                  <ColumnReference Database="[EatecX]" Schema="[dbo]" Table="[rephistory]" Alias="[rh]" Column="intnum" />
                                                </RangeColumns>
                                                <RangeExpressions>
                                                  <ScalarOperator ScalarString="[EatecX].[dbo].[msgdetail].[functionref] as [md].[functionref]">
                                                    <Identifier>
                                                      <ColumnReference Database="[EatecX]" Schema="[dbo]" Table="[msgdetail]" Alias="[md]" Column="functionref" />
                                                    </Identifier>
                                                  </ScalarOperator>
                                                </RangeExpressions>
                                              </Prefix>
                                            </SeekKeys>
                                          </SeekPredicateNew>
                                        </SeekPredicates>
                                      </IndexScan>
                                    </RelOp>
                                  </NestedLoops>
                                </RelOp>
                              </ComputeScalar>
                            </RelOp>
                            <RelOp NodeId="18" PhysicalOp="RID Lookup" LogicalOp="RID Lookup" EstimateRows="1.55557" EstimateIO="0.003125" EstimateCPU="0.0001581" AvgRowSize="561" EstimatedTotalSubtreeCost="0.0478445" TableCardinality="1.42545e+006" Parallel="0" EstimateRebinds="13.5785" EstimateRewinds="0.000275337" EstimatedExecutionMode="Row">
                              <OutputList>
                                <ColumnReference Database="[EatecX]" Schema="[dbo]" Table="[rephistory]" Alias="[rh]" Column="reportid" />
                                <ColumnReference Database="[EatecX]" Schema="[dbo]" Table="[rephistory]" Alias="[rh]" Column="remark" />
                              </OutputList>
                              <IndexScan Lookup="1" Ordered="1" ScanDirection="FORWARD" ForcedIndex="0" ForceSeek="0" ForceScan="0" NoExpandHint="0" Storage="RowStore">
                                <DefinedValues>
                                  <DefinedValue>
                                    <ColumnReference Database="[EatecX]" Schema="[dbo]" Table="[rephistory]" Alias="[rh]" Column="reportid" />
                                  </DefinedValue>
                                  <DefinedValue>
                                    <ColumnReference Database="[EatecX]" Schema="[dbo]" Table="[rephistory]" Alias="[rh]" Column="remark" />
                                  </DefinedValue>
                                </DefinedValues>
                                <Object Database="[EatecX]" Schema="[dbo]" Table="[rephistory]" Alias="[rh]" TableReferenceId="-1" IndexKind="Heap" />
                                <SeekPredicates>
                                  <SeekPredicateNew>
                                    <SeekKeys>
                                      <Prefix ScanType="EQ">
                                        <RangeColumns>
                                          <ColumnReference Column="Bmk1004" />
                                        </RangeColumns>
                                        <RangeExpressions>
                                          <ScalarOperator ScalarString="[Bmk1004]">
                                            <Identifier>
                                              <ColumnReference Column="Bmk1004" />
                                            </Identifier>
                                          </ScalarOperator>
                                        </RangeExpressions>
                                      </Prefix>
                                    </SeekKeys>
                                  </SeekPredicateNew>
                                </SeekPredicates>
                                <Predicate>
                                  <ScalarOperator ScalarString="isnull([EatecX].[dbo].[rephistory].[userid] as [rh].[userid],[@2])=[@3] AND [EatecX].[dbo].[rephistory].[remark] as [rh].[remark] like N''http%''">
                                    <Logical Operation="AND">
                                      <ScalarOperator>
                                        <Compare CompareOp="EQ">
                                          <ScalarOperator>
                                            <Intrinsic FunctionName="isnull">
                                              <ScalarOperator>
                                                <Identifier>
                                                  <ColumnReference Database="[EatecX]" Schema="[dbo]" Table="[rephistory]" Alias="[rh]" Column="userid" />
                                                </Identifier>
                                              </ScalarOperator>
                                              <ScalarOperator>
                                                <Identifier>
                                                  <ColumnReference Column="@2" />
                                                </Identifier>
                                              </ScalarOperator>
                                            </Intrinsic>
                                          </ScalarOperator>
                                          <ScalarOperator>
                                            <Identifier>
                                              <ColumnReference Column="@3" />
                                            </Identifier>
                                          </ScalarOperator>
                                        </Compare>
                                      </ScalarOperator>
                                      <ScalarOperator>
                                        <Intrinsic FunctionName="like">
                                          <ScalarOperator>
                                            <Identifier>
                                              <ColumnReference Database="[EatecX]" Schema="[dbo]" Table="[rephistory]" Alias="[rh]" Column="remark" />
                                            </Identifier>
                                          </ScalarOperator>
                                          <ScalarOperator>
                                            <Const ConstValue="N''http%''" />
                                          </ScalarOperator>
                                        </Intrinsic>
                                      </ScalarOperator>
                                    </Logical>
                                  </ScalarOperator>
                                </Predicate>
                              </IndexScan>
                            </RelOp>
                          </NestedLoops>
                        </RelOp>
                        <RelOp NodeId="24" PhysicalOp="Index Seek" LogicalOp="Index Seek" EstimateRows="1" EstimateIO="0.003125" EstimateCPU="0.0001581" AvgRowSize="11" EstimatedTotalSubtreeCost="0.00980927" TableCardinality="130236" Parallel="0" EstimateRebinds="2.00093" EstimateRewinds="0.000275337" EstimatedExecutionMode="Row">
                          <OutputList>
                            <ColumnReference Database="[EatecX]" Schema="[dbo]" Table="[msghead]" Alias="[mh]" Column="intnum" />
                          </OutputList>
                          <IndexScan Ordered="1" ScanDirection="FORWARD" ForcedIndex="0" ForceSeek="0" ForceScan="0" NoExpandHint="0" Storage="RowStore">
                            <DefinedValues>
                              <DefinedValue>
                                <ColumnReference Database="[EatecX]" Schema="[dbo]" Table="[msghead]" Alias="[mh]" Column="intnum" />
                              </DefinedValue>
                            </DefinedValues>
                            <Object Database="[EatecX]" Schema="[dbo]" Table="[msghead]" Index="[msghead_indx1]" Alias="[mh]" IndexKind="NonClustered" />
                            <SeekPredicates>
                              <SeekPredicateNew>
                                <SeekKeys>
                                  <Prefix ScanType="EQ">
                                    <RangeColumns>
                                      <ColumnReference Database="[EatecX]" Schema="[dbo]" Table="[msghead]" Alias="[mh]" Column="msgintnum" />
                                    </RangeColumns>
                                    <RangeExpressions>
                                      <ScalarOperator ScalarString="[EatecX].[dbo].[msgdetail].[intnum] as [md].[intnum]">
                                        <Identifier>
                                          <ColumnReference Database="[EatecX]" Schema="[dbo]" Table="[msgdetail]" Alias="[md]" Column="intnum" />
                                        </Identifier>
                                      </ScalarOperator>
                                    </RangeExpressions>
                                  </Prefix>
                                </SeekKeys>
                              </SeekPredicateNew>
                            </SeekPredicates>
                          </IndexScan>
                        </RelOp>
                      </NestedLoops>
                    </RelOp>
                    <RelOp NodeId="26" PhysicalOp="Clustered Index Seek" LogicalOp="Clustered Index Seek" EstimateRows="1" EstimateIO="0.003125" EstimateCPU="0.0001581" AvgRowSize="15" EstimatedTotalSubtreeCost="0.00656095" TableCardinality="130236" Parallel="0" EstimateRebinds="1.0003" EstimateRewinds="0" EstimatedExecutionMode="Row">
                      <OutputList />
                      <IndexScan Lookup="1" Ordered="1" ScanDirection="FORWARD" ForcedIndex="0" ForceSeek="0" ForceScan="0" NoExpandHint="0" Storage="RowStore">
                        <DefinedValues />
                        <Object Database="[EatecX]" Schema="[dbo]" Table="[msghead]" Index="[PK_msghead]" Alias="[mh]" TableReferenceId="-1" IndexKind="Clustered" />
                        <SeekPredicates>
                          <SeekPredicateNew>
                            <SeekKeys>
                              <Prefix ScanType="EQ">
                                <RangeColumns>
                                  <ColumnReference Database="[EatecX]" Schema="[dbo]" Table="[msghead]" Alias="[mh]" Column="intnum" />
                                </RangeColumns>
                                <RangeExpressions>
                                  <ScalarOperator ScalarString="[EatecX].[dbo].[msghead].[intnum] as [mh].[intnum]">
                                    <Identifier>
                                      <ColumnReference Database="[EatecX]" Schema="[dbo]" Table="[msghead]" Alias="[mh]" Column="intnum" />
                                    </Identifier>
                                  </ScalarOperator>
                                </RangeExpressions>
                              </Prefix>
                            </SeekKeys>
                          </SeekPredicateNew>
                        </SeekPredicates>
                        <Predicate>
                          <ScalarOperator ScalarString="[EatecX].[dbo].[msghead].[readon] as [mh].[readon]&lt;CONVERT_IMPLICIT(datetime,[@1],0)">
                            <Compare CompareOp="LT">
                              <ScalarOperator>
                                <Identifier>
                                  <ColumnReference Database="[EatecX]" Schema="[dbo]" Table="[msghead]" Alias="[mh]" Column="readon" />
                                </Identifier>
                              </ScalarOperator>
                              <ScalarOperator>
                                <Identifier>
                                  <ColumnReference Column="ConstExpr1007">
                                    <ScalarOperator>
                                      <Convert DataType="datetime" Style="0" Implicit="1">
                                        <ScalarOperator>
                                          <Identifier>
                                            <ColumnReference Column="@1" />
                                          </Identifier>
                                        </ScalarOperator>
                                      </Convert>
                                    </ScalarOperator>
                                  </ColumnReference>
                                </Identifier>
                              </ScalarOperator>
                            </Compare>
                          </ScalarOperator>
                        </Predicate>
                      </IndexScan>
                    </RelOp>
                  </NestedLoops>
                </RelOp>
              </Top>
            </RelOp>
            <ParameterList>
              <ColumnReference Column="@4" ParameterCompiledValue="(45000)" />
              <ColumnReference Column="@3" ParameterCompiledValue="(66)" />
              <ColumnReference Column="@2" ParameterCompiledValue="(0)" />
              <ColumnReference Column="@1" ParameterCompiledValue="''1900/01/02''" />
              <ColumnReference Column="@0" ParameterCompiledValue="(45000)" />
            </ParameterList>
          </QueryPlan>
        </StmtSimple>
      </Statements>
    </Batch>
  </BatchSequence>
</ShowPlanXML>
')

Remember, if the xml plan has single quote around literal, you need to replace single quote ' to two single quotes '', for example, replace '1900/01/02' to ''1900/01/02''.

I tested run it and compared it to the faster plan, they matches and query complete fast as expected.

In other post, I have case study of query store, which stablize the query plan, as what Oracle SPM does.

https://walkthrough-dba.blogspot.com/2021/10/sql-server-query-store-as-oracle-plan.html

Comments

  1. https://www.mssqltips.com/sqlservertip/1630/how-to-use-a-sql-server-plan-guide-to-tune-queries/

    ReplyDelete

Post a Comment

Popular posts from this blog

Opatch apply/lsinventory error: oneoff is corrupted or does not exist

I am applying the quarterly patch for 19c RDBMS, I tried using napply but failed, but somehow it corrupted the inventory though nothing applied. further apply and lsinventory command ran into error like this: $ ./OPatch/opatch lsinventory Oracle Interim Patch Installer version 12.2.0.1.21 Copyright (c) 2020, Oracle Corporation.  All rights reserved. Oracle Home       : /u02/app/oracle/19.0.0 Central Inventory : /u01/app/oraInventory    from           : /u02/app/oracle/19.0.0/oraInst.loc OPatch version    : 12.2.0.1.21 OUI version       : 12.2.0.7.0 Log file location : /u02/app/oracle/19.0.0/cfgtoollogs/opatch/opatch2020-09-08_13-35-59PM_1.log Lsinventory Output file location : /u02/app/oracle/19.0.0/cfgtoollogs/opatch/lsinv/lsinventory2020-09-08_13-35-59PM.txt -------------------------------------------------------------------------------- Inventory load failed... OPatch cannot load inventory ...

oracle dba_hist_sysmetric_summary

found this blog is helpful to get CPU and IO statistics on oracle database. http://shob-dbadmin.blogspot.ca/2012/12/how-to-find-total-io-of-database.html courtesy to  Shomil Bansal , below are hist writing, not mine. How to find total IO of the database instance Total IO of database instance is sum of the physical reads, physical writes and redo writes. There are several views to find these values. v$sysmetric  - Reports metric values for only the most current time sample 60 secs. v$sysmetric_summary  - Reports metric values for time sample of 1 hour. v$sysmetric_history  - Reports metric values every 60 sec from the time instance is up. Better way to analyse IO using this view to take deltas between two time periods. dba_hist_sysmetric_history  - All the above views are refreshed when the instance is restarted. This view, part of AWR, stores the historical stats. I have used this view for my report. Query: ====== set lines 350...

ORA_RMAN_SGA_TARGET

assume that we lost all the files of oracle database but we do have rman backup, when trying to bring up a dummy database before restore start, I get this error. RMAN> startup nomount force; WARNING: cannot translate ORA_RMAN_SGA_TARGET value startup failed: ORA-01078: failure in processing system parameters ORA-01565: error in identifying file '+DATA/PROD/spfilePROD.ora' ORA-17503: ksfdopn:2 Failed to open file +DATA/PROD/spfilePROD.ora ORA-15056: additional error message ORA-17503: ksfdopn:DGOpenFile05 Failed to open file +DATA/prod/spfileprod.ora ORA-17503: ksfdopn:2 Failed to open file +DATA/prod/spfileprod.ora ORA-15173: entry 'spfileprod.ora' does not exist in directory 'prod' ORA-06512: at line 4 starting Oracle instance without parameter file for retrival of spfile RMAN-00571: =========================================================== RMAN-00569: =============== ERROR MESSAGE STACK FOLLOWS =============== RMAN-00571: =================================...