2010-06-21 276 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