2010-06-21 292 views
0

今天,我发现在我们的代码此查询拉从我们的数据库错误列表:什么是查询执行到SQL Server 2005中的此查询?

SELECT * 
FROM (
     SELECT Substring(title, 9, Patindex('%)%', title) - 9) AS SERVICE, * 
     FROM core.LOG 
     WHERE logtypeid = 1 
       AND title LIKE 'Error: (%' 
       AND lastmodified > '2010-06-21T00:00:00' 
       AND lastmodified < '2010-06-22T00:00:00' 
     ) serviceerrors 
WHERE SERVICE = 'CheckHelpDeskEmail' 

它失败,出现以下错误:

Invalid length parameter passed to the SUBSTRING function.

如果我卸下了WHERE条款最后一行它工作正常。或者,如果我从内部子查询中获取WHERE子句并将其移动到主查询中,它可以正常工作。所以这个作品:

SELECT * 
FROM (
     SELECT Substring(title, 9, Patindex('%)%', title) - 9) AS SERVICE, * 
     FROM core.LOG 
     ) serviceerrors 
WHERE logtypeid = 1 
AND title LIKE 'Error: (%' 
AND lastmodified > '2010-06-21T00:00:00' 
AND lastmodified < '2010-06-22T00:00:00' 
AND SERVICE = 'CheckHelpDeskEmail' 

有谁知道为什么?我认为问题在于SQL实际上是通过core.LOG表进行多次运行,并且第一次只是在整个表上运行子串行,因为一些行不会有')'。但是,如果它运行WHERE子句中的其余行,则不会找到缺少')'的行。然后再次运行core.LOG表并运行剩余的过滤器。这看起来效率不高,因为它最终会在数百万行上运行Substring函数,而从WHERE子句中的剩余过滤器开始大约有15行。

这里是我的XML执行计划

<?xml version="1.0" encoding="utf-16"?> 
<ShowPlanXML xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" Version="1.0" Build="9.00.3310.00" xmlns="http://schemas.microsoft.com/sqlserver/2004/07/showplan"> 
    <BatchSequence> 
    <Batch> 
     <Statements> 
     <StmtSimple StatementCompId="1" StatementEstRows="1" StatementId="1" StatementOptmLevel="FULL" StatementSubTreeCost="36.4574" StatementText="SELECT *&#xD;&#xA;FROM (&#xD;&#xA;  SELECT Substring(title, 9, Patindex('%)%', title) - 9) AS SERVICE,&#xD;&#xA;    *&#xD;&#xA;  FROM core.LOG&#xD;&#xA;  WHERE logtypeid = 1&#xD;&#xA;    AND title LIKE 'Error: (%'&#xD;&#xA;    AND lastmodified &gt; '2010-06-21T00:00:00'&#xD;&#xA;    AND lastmodified &lt; '2010-06-22T00:00:00'&#xD;&#xA;  ) serviceerrors&#xD;&#xA;WHERE SERVICE = 'CheckHelpDeskEmail' &#xD;&#xA;" StatementType="SELECT"> 
      <StatementSetOptions ANSI_NULLS="false" ANSI_PADDING="false" ANSI_WARNINGS="false" ARITHABORT="true" CONCAT_NULL_YIELDS_NULL="false" NUMERIC_ROUNDABORT="false" QUOTED_IDENTIFIER="false" /> 
      <QueryPlan CachedPlanSize="47" CompileTime="10" CompileCPU="7" CompileMemory="544"> 
      <RelOp AvgRowSize="4544" EstimateCPU="1E-07" EstimateIO="0" EstimateRebinds="0" EstimateRewinds="0" EstimateRows="1" LogicalOp="Compute Scalar" NodeId="0" Parallel="false" PhysicalOp="Compute Scalar" EstimatedTotalSubtreeCost="36.4574"> 
       <OutputList> 
       <ColumnReference Database="[Aqueduct]" Schema="[Core]" Table="[Log]" Column="LogId" /> 
       <ColumnReference Database="[Aqueduct]" Schema="[Core]" Table="[Log]" Column="Title" /> 
       <ColumnReference Database="[Aqueduct]" Schema="[Core]" Table="[Log]" Column="Details" /> 
       <ColumnReference Database="[Aqueduct]" Schema="[Core]" Table="[Log]" Column="IdentifierHash" /> 
       <ColumnReference Database="[Aqueduct]" Schema="[Core]" Table="[Log]" Column="LastModifier" /> 
       <ColumnReference Database="[Aqueduct]" Schema="[Core]" Table="[Log]" Column="LastModified" /> 
       <ColumnReference Database="[Aqueduct]" Schema="[Core]" Table="[Log]" Column="LogTypeId" /> 
       <ColumnReference Column="Expr1003" /> 
       </OutputList> 
       <ComputeScalar> 
       <DefinedValues> 
        <DefinedValue> 
        <ColumnReference Column="Expr1003" /> 
        <ScalarOperator ScalarString="substring([Aqueduct].[Core].[Log].[Title],(9),patindex(N'%)%',[Aqueduct].[Core].[Log].[Title])-(9))"> 
         <Intrinsic FunctionName="substring"> 
         <ScalarOperator> 
          <Identifier> 
          <ColumnReference Database="[Aqueduct]" Schema="[Core]" Table="[Log]" Column="Title" /> 
          </Identifier> 
         </ScalarOperator> 
         <ScalarOperator> 
          <Const ConstValue="(9)" /> 
         </ScalarOperator> 
         <ScalarOperator> 
          <Arithmetic Operation="SUB"> 
          <ScalarOperator> 
           <Intrinsic FunctionName="patindex"> 
           <ScalarOperator> 
            <Const ConstValue="N'%)%'" /> 
           </ScalarOperator> 
           <ScalarOperator> 
            <Identifier> 
            <ColumnReference Database="[Aqueduct]" Schema="[Core]" Table="[Log]" Column="Title" /> 
            </Identifier> 
           </ScalarOperator> 
           </Intrinsic> 
          </ScalarOperator> 
          <ScalarOperator> 
           <Const ConstValue="(9)" /> 
          </ScalarOperator> 
          </Arithmetic> 
         </ScalarOperator> 
         </Intrinsic> 
        </ScalarOperator> 
        </DefinedValue> 
       </DefinedValues> 
       <RelOp AvgRowSize="4342" EstimateCPU="0.0288036" EstimateIO="0" EstimateRebinds="0" EstimateRewinds="0" EstimateRows="1" LogicalOp="Gather Streams" NodeId="1" Parallel="true" PhysicalOp="Parallelism" EstimatedTotalSubtreeCost="36.4574"> 
        <OutputList> 
        <ColumnReference Database="[Aqueduct]" Schema="[Core]" Table="[Log]" Column="LogId" /> 
        <ColumnReference Database="[Aqueduct]" Schema="[Core]" Table="[Log]" Column="Title" /> 
        <ColumnReference Database="[Aqueduct]" Schema="[Core]" Table="[Log]" Column="Details" /> 
        <ColumnReference Database="[Aqueduct]" Schema="[Core]" Table="[Log]" Column="IdentifierHash" /> 
        <ColumnReference Database="[Aqueduct]" Schema="[Core]" Table="[Log]" Column="LastModifier" /> 
        <ColumnReference Database="[Aqueduct]" Schema="[Core]" Table="[Log]" Column="LastModified" /> 
        <ColumnReference Database="[Aqueduct]" Schema="[Core]" Table="[Log]" Column="LogTypeId" /> 
        </OutputList> 
        <Parallelism> 
        <RelOp AvgRowSize="4342" EstimateCPU="0.0128582" EstimateIO="0" EstimateRebinds="0" EstimateRewinds="0" EstimateRows="1" LogicalOp="Filter" NodeId="2" Parallel="true" PhysicalOp="Filter" EstimatedTotalSubtreeCost="36.4286"> 
         <OutputList> 
         <ColumnReference Database="[Aqueduct]" Schema="[Core]" Table="[Log]" Column="LogId" /> 
         <ColumnReference Database="[Aqueduct]" Schema="[Core]" Table="[Log]" Column="Title" /> 
         <ColumnReference Database="[Aqueduct]" Schema="[Core]" Table="[Log]" Column="Details" /> 
         <ColumnReference Database="[Aqueduct]" Schema="[Core]" Table="[Log]" Column="IdentifierHash" /> 
         <ColumnReference Database="[Aqueduct]" Schema="[Core]" Table="[Log]" Column="LastModifier" /> 
         <ColumnReference Database="[Aqueduct]" Schema="[Core]" Table="[Log]" Column="LastModified" /> 
         <ColumnReference Database="[Aqueduct]" Schema="[Core]" Table="[Log]" Column="LogTypeId" /> 
         </OutputList> 
         <Filter StartupExpression="false"> 
         <RelOp AvgRowSize="4342" EstimateCPU="0.0235734" EstimateIO="0" EstimateRebinds="0" EstimateRewinds="0" EstimateRows="11279.1" LogicalOp="Inner Join" NodeId="3" Parallel="true" PhysicalOp="Nested Loops" EstimatedTotalSubtreeCost="36.4157"> 
          <OutputList> 
          <ColumnReference Database="[Aqueduct]" Schema="[Core]" Table="[Log]" Column="LogId" /> 
          <ColumnReference Database="[Aqueduct]" Schema="[Core]" Table="[Log]" Column="Title" /> 
          <ColumnReference Database="[Aqueduct]" Schema="[Core]" Table="[Log]" Column="Details" /> 
          <ColumnReference Database="[Aqueduct]" Schema="[Core]" Table="[Log]" Column="IdentifierHash" /> 
          <ColumnReference Database="[Aqueduct]" Schema="[Core]" Table="[Log]" Column="LastModifier" /> 
          <ColumnReference Database="[Aqueduct]" Schema="[Core]" Table="[Log]" Column="LastModified" /> 
          <ColumnReference Database="[Aqueduct]" Schema="[Core]" Table="[Log]" Column="LogTypeId" /> 
          </OutputList> 
          <NestedLoops Optimized="true" WithUnorderedPrefetch="true"> 
          <OuterReferences> 
           <ColumnReference Database="[Aqueduct]" Schema="[Core]" Table="[Log]" Column="LogId" /> 
           <ColumnReference Column="Expr1004" /> 
          </OuterReferences> 
          <RelOp AvgRowSize="19" EstimateCPU="0.00628203" EstimateIO="0.0186806" EstimateRebinds="0" EstimateRewinds="0" EstimateRows="11279.1" LogicalOp="Index Seek" NodeId="6" Parallel="true" PhysicalOp="Index Seek" EstimatedTotalSubtreeCost="0.0249626"> 
           <OutputList> 
           <ColumnReference Database="[Aqueduct]" Schema="[Core]" Table="[Log]" Column="LogId" /> 
           <ColumnReference Database="[Aqueduct]" Schema="[Core]" Table="[Log]" Column="LastModified" /> 
           </OutputList> 
           <IndexScan Ordered="true" ScanDirection="FORWARD" ForcedIndex="false" NoExpandHint="false"> 
           <DefinedValues> 
            <DefinedValue> 
            <ColumnReference Database="[Aqueduct]" Schema="[Core]" Table="[Log]" Column="LogId" /> 
            </DefinedValue> 
            <DefinedValue> 
            <ColumnReference Database="[Aqueduct]" Schema="[Core]" Table="[Log]" Column="LastModified" /> 
            </DefinedValue> 
           </DefinedValues> 
           <Object Database="[Aqueduct]" Schema="[Core]" Table="[Log]" Index="[IX_LastModified]" /> 
           <SeekPredicates> 
            <SeekPredicate> 
            <StartRange ScanType="GT"> 
             <RangeColumns> 
             <ColumnReference Database="[Aqueduct]" Schema="[Core]" Table="[Log]" Column="LastModified" /> 
             </RangeColumns> 
             <RangeExpressions> 
             <ScalarOperator ScalarString="'2010-06-21 00:00:00.000'"> 
              <Const ConstValue="'2010-06-21 00:00:00.000'" /> 
             </ScalarOperator> 
             </RangeExpressions> 
            </StartRange> 
            <EndRange ScanType="LT"> 
             <RangeColumns> 
             <ColumnReference Database="[Aqueduct]" Schema="[Core]" Table="[Log]" Column="LastModified" /> 
             </RangeColumns> 
             <RangeExpressions> 
             <ScalarOperator ScalarString="'2010-06-22 00:00:00.000'"> 
              <Const ConstValue="'2010-06-22 00:00:00.000'" /> 
             </ScalarOperator> 
             </RangeExpressions> 
            </EndRange> 
            </SeekPredicate> 
           </SeekPredicates> 
           </IndexScan> 
          </RelOp> 
          <RelOp AvgRowSize="4447" EstimateCPU="0.0001581" EstimateIO="0.003125" EstimateRebinds="11278.1" EstimateRewinds="0" EstimateRows="1" LogicalOp="Clustered Index Seek" NodeId="8" Parallel="true" PhysicalOp="Clustered Index Seek" EstimatedTotalSubtreeCost="36.3672"> 
           <OutputList> 
           <ColumnReference Database="[Aqueduct]" Schema="[Core]" Table="[Log]" Column="Title" /> 
           <ColumnReference Database="[Aqueduct]" Schema="[Core]" Table="[Log]" Column="Details" /> 
           <ColumnReference Database="[Aqueduct]" Schema="[Core]" Table="[Log]" Column="IdentifierHash" /> 
           <ColumnReference Database="[Aqueduct]" Schema="[Core]" Table="[Log]" Column="LastModifier" /> 
           <ColumnReference Database="[Aqueduct]" Schema="[Core]" Table="[Log]" Column="LogTypeId" /> 
           </OutputList> 
           <IndexScan Lookup="true" Ordered="true" ScanDirection="FORWARD" ForcedIndex="false" NoExpandHint="false"> 
           <DefinedValues> 
            <DefinedValue> 
            <ColumnReference Database="[Aqueduct]" Schema="[Core]" Table="[Log]" Column="Title" /> 
            </DefinedValue> 
            <DefinedValue> 
            <ColumnReference Database="[Aqueduct]" Schema="[Core]" Table="[Log]" Column="Details" /> 
            </DefinedValue> 
            <DefinedValue> 
            <ColumnReference Database="[Aqueduct]" Schema="[Core]" Table="[Log]" Column="IdentifierHash" /> 
            </DefinedValue> 
            <DefinedValue> 
            <ColumnReference Database="[Aqueduct]" Schema="[Core]" Table="[Log]" Column="LastModifier" /> 
            </DefinedValue> 
            <DefinedValue> 
            <ColumnReference Database="[Aqueduct]" Schema="[Core]" Table="[Log]" Column="LogTypeId" /> 
            </DefinedValue> 
           </DefinedValues> 
           <Object Database="[Aqueduct]" Schema="[Core]" Table="[Log]" Index="[PK_Core_Log]" TableReferenceId="-1" /> 
           <SeekPredicates> 
            <SeekPredicate> 
            <Prefix ScanType="EQ"> 
             <RangeColumns> 
             <ColumnReference Database="[Aqueduct]" Schema="[Core]" Table="[Log]" Column="LogId" /> 
             </RangeColumns> 
             <RangeExpressions> 
             <ScalarOperator ScalarString="[Aqueduct].[Core].[Log].[LogId]"> 
              <Identifier> 
              <ColumnReference Database="[Aqueduct]" Schema="[Core]" Table="[Log]" Column="LogId" /> 
              </Identifier> 
             </ScalarOperator> 
             </RangeExpressions> 
            </Prefix> 
            </SeekPredicate> 
           </SeekPredicates> 
           </IndexScan> 
          </RelOp> 
          </NestedLoops> 
         </RelOp> 
         <Predicate> 
          <ScalarOperator ScalarString="substring([Aqueduct].[Core].[Log].[Title],(9),patindex(N'%)%',[Aqueduct].[Core].[Log].[Title])-(9))=N'CheckHelpDeskEmail' AND [Aqueduct].[Core].[Log].[Title] like N'Error: (%' AND [Aqueduct].[Core].[Log].[LogTypeId]=(1)"> 
          <Logical Operation="AND"> 
           <ScalarOperator> 
           <Compare CompareOp="EQ"> 
            <ScalarOperator> 
            <Intrinsic FunctionName="substring"> 
             <ScalarOperator> 
             <Identifier> 
              <ColumnReference Database="[Aqueduct]" Schema="[Core]" Table="[Log]" Column="Title" /> 
             </Identifier> 
             </ScalarOperator> 
             <ScalarOperator> 
             <Const ConstValue="(9)" /> 
             </ScalarOperator> 
             <ScalarOperator> 
             <Arithmetic Operation="SUB"> 
              <ScalarOperator> 
              <Intrinsic FunctionName="patindex"> 
               <ScalarOperator> 
               <Const ConstValue="N'%)%'" /> 
               </ScalarOperator> 
               <ScalarOperator> 
               <Identifier> 
                <ColumnReference Database="[Aqueduct]" Schema="[Core]" Table="[Log]" Column="Title" /> 
               </Identifier> 
               </ScalarOperator> 
              </Intrinsic> 
              </ScalarOperator> 
              <ScalarOperator> 
              <Const ConstValue="(9)" /> 
              </ScalarOperator> 
             </Arithmetic> 
             </ScalarOperator> 
            </Intrinsic> 
            </ScalarOperator> 
            <ScalarOperator> 
            <Const ConstValue="N'CheckHelpDeskEmail'" /> 
            </ScalarOperator> 
           </Compare> 
           </ScalarOperator> 
           <ScalarOperator> 
           <Intrinsic FunctionName="like"> 
            <ScalarOperator> 
            <Identifier> 
             <ColumnReference Database="[Aqueduct]" Schema="[Core]" Table="[Log]" Column="Title" /> 
            </Identifier> 
            </ScalarOperator> 
            <ScalarOperator> 
            <Const ConstValue="N'Error: (%'" /> 
            </ScalarOperator> 
           </Intrinsic> 
           </ScalarOperator> 
           <ScalarOperator> 
           <Compare CompareOp="EQ"> 
            <ScalarOperator> 
            <Identifier> 
             <ColumnReference Database="[Aqueduct]" Schema="[Core]" Table="[Log]" Column="LogTypeId" /> 
            </Identifier> 
            </ScalarOperator> 
            <ScalarOperator> 
            <Const ConstValue="(1)" /> 
            </ScalarOperator> 
           </Compare> 
           </ScalarOperator> 
          </Logical> 
          </ScalarOperator> 
         </Predicate> 
         </Filter> 
        </RelOp> 
        </Parallelism> 
       </RelOp> 
       </ComputeScalar> 
      </RelOp> 
      </QueryPlan> 
     </StmtSimple> 
     </Statements> 
    </Batch> 
    </BatchSequence> 
</ShowPlanXML> 
+0

你可以发布XML计划吗? – 2010-06-21 22:00:11

+0

我添加了XML。 – kd7iwp 2010-06-21 22:13:33

+0

是的,您可以在计划中看到,首先它会从IX_LastModified上的索引查找中获得与日期范围匹配的估计11,279行,然后在相同的过滤器操作中将所有其他谓词应用到一起。我不确定在计划本身的单个“过滤器”步骤*中是否可以读取布尔操作的顺序*?如果可以的话,它首先评估子字符串。 '子(。[核心] [记录] [标题],(9),PATINDEX(N '%)%',[核心] [日志] [标题]。。) - (9))= N'CheckHelpDeskEmail” AND [Core]。[Log]。[Title] like N'Error:(%'AND [Core]。[Log]。[LogTypeId] =(1)'。 – 2010-06-21 23:12:46

回答

4

您的代码进行无效的假设。在像SQL这样的声明式集合导向语言中,执行可以自由选择任何它认为合适的执行计划。你认为效率低下的情况很可能是一个有效的优化,其中标题首先从满足lastmodified或类似的谓词的索引投影。您无法对执行顺序进行任何假设,因此不允许在投影列表中显示像SUBSTRING(..,9,..)这样的表达式,这些表达式将在某些行上进行轰炸。

另一个类似无效假设产生的问题的例子是SQL Server boolean operator short-circuit评估错误。

+0

谢谢,这是有道理的,我不能承担任何执行顺序。 – kd7iwp 2010-06-21 22:13:16