慢速SQL 2008游标性能 - 索引扫描/搜索

时间:2013-07-31 13:38:21

标签: sql-server sql-server-2008 indexing cursor

在使用sql server 2008的ADO驱动程序时(或者更确切地说,当使用由驱动程序创建的特定sql游标时),我发现了一些有趣的“问题”。 我们想执行以下查询:

SELECT ID, TelEveID, TelDayID, TelMobID, QualityFlag, WeekBegin FROM CEF 
WHERE (TelEveID = '+44xxxx') OR (TelDayID = '+44xxxxx') OR (TelMobID = '+44xxxx') 
ORDER BY ID DESC

其中有(为了示例)三个在CEF表上为元组索引[ID; TelEveID],[ID; TelDayID]和[ID; TelMobID]

上面的查询由驱动程序以下列方式“翻译”:

declare @p1 int
declare @p2 int
declare @p5 int
set @p5=4
declare @p6 int
set @p6=4
declare @p7 int
set @p7=-1
exec sp_cursorprepexec @p1 output,@p2 output,NULL,N'SELECT ID, TelEveID, TelDayID, TelMobID, QualityFlag, WeekBegin FROM CEF WHERE (TelEveID = ''+44xxxx'') OR (TelDayID = ''+44xxxx'') OR (TelMobID = ''+44xxxx'') ORDER BY ID DESC',@p5 output,@p6 output,@p7 output
exec sp_cursorfetch @p2,2,1,10

问题是,如果你执行上面的查询,首先是约。比第二个快10倍。如果我们看一下实际的执行计划,我们可以看出差异的原因

Execution plan

Cursor完全省略现有索引,而是使用Index Scan,而“direct query”将三个“单独”结果集合并到具有适当索引用法的最终结果集中。

如果我在游标定义中更改“WHERE”部分,使其仅查看一个字段,它将使用适当的索引(由于游标的运行成本,它仍然较慢)。

有没有办法在不完全删除游标的情况下避免这种行为(因为在执行此操作的遗留应用程序中这是不可能的)?

由于

Martin F。

这是(稍微缩短 - 我已经删除了有关CEF表中所有列的信息)(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.1" Build="10.50.1617.0" xmlns="http://schemas.microsoft.com/sqlserver/2004/07/showplan">
  <BatchSequence>
    <Batch>
      <Statements>
        <StmtSimple StatementCompId="6" StatementEstRows="3.3163" StatementId="1" StatementOptmLevel="FULL" StatementSubTreeCost="134.243" StatementText="SELECT ID, TelEveID, TelDayID, TelMobID, QualityFlag, WeekBegin FROM CEF WHERE (TelEveID = '+44xxxx') OR (TelDayID = '+44xxxx') OR (TelMobID = '+44xxxx') ORDER BY ID DESC" StatementType="DECLARE CURSOR" QueryHash="0x4DC45EB62BCCAE06" QueryPlanHash="0x72ACC7B98E06E06E">
          <StatementSetOptions ANSI_NULLS="true" ANSI_PADDING="true" ANSI_WARNINGS="true" ARITHABORT="true" CONCAT_NULL_YIELDS_NULL="true" NUMERIC_ROUNDABORT="false" QUOTED_IDENTIFIER="true" />
          <QueryPlan DegreeOfParallelism="0" CachedPlanSize="152" CompileTime="7" CompileCPU="3" CompileMemory="992">
            <RelOp AvgRowSize="913" EstimateCPU="3.3163E-06" EstimateIO="0.01" EstimateRebinds="0" EstimateRewinds="0" EstimateRows="3.3163" LogicalOp="Insert" NodeId="0" Parallel="false" PhysicalOp="Clustered Index Insert" EstimatedTotalSubtreeCost="134.243">
              <OutputList>
                <ColumnReference Database="[LMS]" Schema="[dbo]" Table="[CEF]" Column="ID" />
                <ColumnReference Database="[LMS]" Schema="[dbo]" Table="[CEF]" Column="TelEveID" />
                <ColumnReference Database="[LMS]" Schema="[dbo]" Table="[CEF]" Column="TelDayID" />
                <ColumnReference Database="[LMS]" Schema="[dbo]" Table="[CEF]" Column="TelMobID" />
                <ColumnReference Column="Expr1005" />
              </OutputList>
              <RunTimeInformation>
                <RunTimeCountersPerThread Thread="0" ActualRows="0" ActualEndOfScans="0" ActualExecutions="1" />
              </RunTimeInformation>
              <Update DMLRequestSort="false">
                <Object Database="[tempdb]" Index="[CWT_PrimaryKey]" />
                <SetPredicate>
                  <ScalarOperator ScalarString="[CWT].[COLUMN0] = [LMS].[dbo].[CEF].[ID],[CWT].[CHECKSUM1] = [Chk1002],[CWT].[ROWID] = [Expr1005]">
                    <ScalarExpressionList>
                      <ScalarOperator>
                        <MultipleAssign>
                          <Assign>
                            <ColumnReference Table="[CWT]" Column="COLUMN0" />
                            <ScalarOperator>
                              <Identifier>
                                <ColumnReference Database="[LMS]" Schema="[dbo]" Table="[CEF]" Column="ID" />
                              </Identifier>
                            </ScalarOperator>
                          </Assign>
                          <Assign>
                            <ColumnReference Table="[CWT]" Column="CHECKSUM1" />
                            <ScalarOperator>
                              <Identifier>
                                <ColumnReference Column="Chk1002" />
                              </Identifier>
                            </ScalarOperator>
                          </Assign>
                          <Assign>
                            <ColumnReference Table="[CWT]" Column="ROWID" />
                            <ScalarOperator>
                              <Identifier>
                                <ColumnReference Column="Expr1005" />
                              </Identifier>
                            </ScalarOperator>
                          </Assign>
                        </MultipleAssign>
                      </ScalarOperator>
                    </ScalarExpressionList>
                  </ScalarOperator>
                </SetPredicate>
                <RelOp AvgRowSize="917" EstimateCPU="3.3163E-07" EstimateIO="0" EstimateRebinds="0" EstimateRewinds="0" EstimateRows="3.3163" LogicalOp="Compute Scalar" NodeId="1" Parallel="false" PhysicalOp="Compute Scalar" EstimatedTotalSubtreeCost="134.233">
                  <OutputList>
                    <ColumnReference Column="Chk1002" />
                    <ColumnReference Database="[LMS]" Schema="[dbo]" Table="[CEF]" Column="ID" />
                    <ColumnReference Database="[LMS]" Schema="[dbo]" Table="[CEF]" Column="TelEveID" />
                    <ColumnReference Database="[LMS]" Schema="[dbo]" Table="[CEF]" Column="TelDayID" />
                    <ColumnReference Database="[LMS]" Schema="[dbo]" Table="[CEF]" Column="TelMobID" />
                    <ColumnReference Column="Expr1005" />
                  </OutputList>
                  <RunTimeInformation>
                    <RunTimeCountersPerThread Thread="0" ActualRows="0" ActualEndOfScans="0" ActualExecutions="1" />
                  </RunTimeInformation>
                  <ComputeScalar>
                    <DefinedValues>
                      <DefinedValue>
                        <ColumnReference Column="Expr1005" />
                        <ScalarOperator ScalarString="CWT_ROWID()">
                          <Intrinsic FunctionName="CWT_ROWID" />
                        </ScalarOperator>
                      </DefinedValue>
                    </DefinedValues>
                    <RelOp AvgRowSize="913" EstimateCPU="1.68105" EstimateIO="130.748" EstimateRebinds="0" EstimateRewinds="0" EstimateRows="3.3163" LogicalOp="Clustered Index Scan" NodeId="2" Parallel="false" PhysicalOp="Clustered Index Scan" EstimatedTotalSubtreeCost="132.429" TableCardinality="1528090">
                      <OutputList>
                        <ColumnReference Column="Chk1002" />
                        <ColumnReference Database="[LMS]" Schema="[dbo]" Table="[CEF]" Column="ID" />
                        <ColumnReference Database="[LMS]" Schema="[dbo]" Table="[CEF]" Column="TelEveID" />
                        <ColumnReference Database="[LMS]" Schema="[dbo]" Table="[CEF]" Column="TelDayID" />
                        <ColumnReference Database="[LMS]" Schema="[dbo]" Table="[CEF]" Column="TelMobID" />
                      </OutputList>
                      <RunTimeInformation>
                        <RunTimeCountersPerThread Thread="0" ActualRows="0" ActualEndOfScans="0" ActualExecutions="1" />
                      </RunTimeInformation>
                      <IndexScan Ordered="true" ScanDirection="BACKWARD" ForcedIndex="false" ForceSeek="false" NoExpandHint="false">
                        <DefinedValues>
                          <DefinedValue>
                            <ColumnReference Column="Chk1002" />
                          </DefinedValue>
                          <DefinedValue>
                            <ColumnReference Database="[LMS]" Schema="[dbo]" Table="[CEF]" Column="ID" />
                          </DefinedValue>
                          <DefinedValue>
                            <ColumnReference Database="[LMS]" Schema="[dbo]" Table="[CEF]" Column="TelEveID" />
                          </DefinedValue>
                          <DefinedValue>
                            <ColumnReference Database="[LMS]" Schema="[dbo]" Table="[CEF]" Column="TelDayID" />
                          </DefinedValue>
                          <DefinedValue>
                            <ColumnReference Database="[LMS]" Schema="[dbo]" Table="[CEF]" Column="TelMobID" />
                          </DefinedValue>
                        </DefinedValues>
                        <Object Database="[LMS]" Schema="[dbo]" Table="[CEF]" Index="[PK_CEF]" IndexKind="Clustered" />
                        <Predicate>
                          <ScalarOperator ScalarString="[LMS].[dbo].[CEF].[TelEveID]='+44xxxx' OR [LMS].[dbo].[CEF].[TelDayID]='+44xxxx' OR [LMS].[dbo].[CEF].[TelMobID]='+44xxxx'">
                            <Logical Operation="OR">
                              <ScalarOperator>
                                <Compare CompareOp="EQ">
                                  <ScalarOperator>
                                    <Identifier>
                                      <ColumnReference Database="[LMS]" Schema="[dbo]" Table="[CEF]" Column="TelEveID" />
                                    </Identifier>
                                  </ScalarOperator>
                                  <ScalarOperator>
                                    <Const ConstValue="'+44xxxx'" />
                                  </ScalarOperator>
                                </Compare>
                              </ScalarOperator>
                              <ScalarOperator>
                                <Compare CompareOp="EQ">
                                  <ScalarOperator>
                                    <Identifier>
                                      <ColumnReference Database="[LMS]" Schema="[dbo]" Table="[CEF]" Column="TelDayID" />
                                    </Identifier>
                                  </ScalarOperator>
                                  <ScalarOperator>
                                    <Const ConstValue="'+44xxxx'" />
                                  </ScalarOperator>
                                </Compare>
                              </ScalarOperator>
                              <ScalarOperator>
                                <Compare CompareOp="EQ">
                                  <ScalarOperator>
                                    <Identifier>
                                      <ColumnReference Database="[LMS]" Schema="[dbo]" Table="[CEF]" Column="TelMobID" />
                                    </Identifier>
                                  </ScalarOperator>
                                  <ScalarOperator>
                                    <Const ConstValue="'+44xxxx'" />
                                  </ScalarOperator>
                                </Compare>
                              </ScalarOperator>
                            </Logical>
                          </ScalarOperator>
                        </Predicate>
                      </IndexScan>
                    </RelOp>
                  </ComputeScalar>
                </RelOp>
              </Update>
            </RelOp>
          </QueryPlan>
        </StmtSimple>
      </Statements>
    </Batch>
    <Batch>
      <Statements>
        <StmtSimple StatementCompId="7" StatementEstRows="3.3163" StatementId="2" StatementOptmLevel="FULL" StatementSubTreeCost="134.243" StatementText="FETCH API_CURSOR000000000007AA17" StatementType="FETCH CURSOR" QueryHash="0x4DC45EB62BCCAE06" QueryPlanHash="0x72ACC7B98E06E06E">
          <StatementSetOptions ANSI_NULLS="true" ANSI_PADDING="true" ANSI_WARNINGS="true" ARITHABORT="true" CONCAT_NULL_YIELDS_NULL="true" NUMERIC_ROUNDABORT="false" QUOTED_IDENTIFIER="true" />
          <QueryPlan DegreeOfParallelism="0" CachedPlanSize="152" CompileTime="7" CompileCPU="3" CompileMemory="992">
            <RelOp AvgRowSize="913" EstimateCPU="3.3163E-06" EstimateIO="0.01" EstimateRebinds="0" EstimateRewinds="0" EstimateRows="3.3163" LogicalOp="Insert" NodeId="0" Parallel="false" PhysicalOp="Clustered Index Insert" EstimatedTotalSubtreeCost="134.243">
              <OutputList>
                <ColumnReference Database="[LMS]" Schema="[dbo]" Table="[CEF]" Column="ID" />
                <ColumnReference Database="[LMS]" Schema="[dbo]" Table="[CEF]" Column="TelEveID" />
                <ColumnReference Database="[LMS]" Schema="[dbo]" Table="[CEF]" Column="TelDayID" />
                <ColumnReference Database="[LMS]" Schema="[dbo]" Table="[CEF]" Column="TelMobID" />
                <ColumnReference Column="Expr1005" />
              </OutputList>
              <RunTimeInformation>
                <RunTimeCountersPerThread Thread="0" ActualRows="1" ActualEndOfScans="1" ActualExecutions="1" />
              </RunTimeInformation>
              <Update DMLRequestSort="false">
                <Object Database="[tempdb]" Index="[CWT_PrimaryKey]" />
                <SetPredicate>
                  <ScalarOperator ScalarString="[CWT].[COLUMN0] = [LMS].[dbo].[CEF].[ID],[CWT].[CHECKSUM1] = [Chk1002],[CWT].[ROWID] = [Expr1005]">
                    <ScalarExpressionList>
                      <ScalarOperator>
                        <MultipleAssign>
                          <Assign>
                            <ColumnReference Table="[CWT]" Column="COLUMN0" />
                            <ScalarOperator>
                              <Identifier>
                                <ColumnReference Database="[LMS]" Schema="[dbo]" Table="[CEF]" Column="ID" />
                              </Identifier>
                            </ScalarOperator>
                          </Assign>
                          <Assign>
                            <ColumnReference Table="[CWT]" Column="CHECKSUM1" />
                            <ScalarOperator>
                              <Identifier>
                                <ColumnReference Column="Chk1002" />
                              </Identifier>
                            </ScalarOperator>
                          </Assign>
                          <Assign>
                            <ColumnReference Table="[CWT]" Column="ROWID" />
                            <ScalarOperator>
                              <Identifier>
                                <ColumnReference Column="Expr1005" />
                              </Identifier>
                            </ScalarOperator>
                          </Assign>
                        </MultipleAssign>
                      </ScalarOperator>
                    </ScalarExpressionList>
                  </ScalarOperator>
                </SetPredicate>
                <RelOp AvgRowSize="917" EstimateCPU="3.3163E-07" EstimateIO="0" EstimateRebinds="0" EstimateRewinds="0" EstimateRows="3.3163" LogicalOp="Compute Scalar" NodeId="1" Parallel="false" PhysicalOp="Compute Scalar" EstimatedTotalSubtreeCost="134.233">
                  <OutputList>
                    <ColumnReference Column="Chk1002" />
                    <ColumnReference Database="[LMS]" Schema="[dbo]" Table="[CEF]" Column="ID" />
                    <ColumnReference Database="[LMS]" Schema="[dbo]" Table="[CEF]" Column="TelEveID" />
                    <ColumnReference Database="[LMS]" Schema="[dbo]" Table="[CEF]" Column="TelDayID" />
                    <ColumnReference Database="[LMS]" Schema="[dbo]" Table="[CEF]" Column="TelMobID" />
                    <ColumnReference Column="Expr1005" />
                  </OutputList>
                  <RunTimeInformation>
                    <RunTimeCountersPerThread Thread="0" ActualRows="1" ActualEndOfScans="1" ActualExecutions="1" />
                  </RunTimeInformation>
                  <ComputeScalar>
                    <DefinedValues>
                      <DefinedValue>
                        <ColumnReference Column="Expr1005" />
                        <ScalarOperator ScalarString="CWT_ROWID()">
                          <Intrinsic FunctionName="CWT_ROWID" />
                        </ScalarOperator>
                      </DefinedValue>
                    </DefinedValues>
                    <RelOp AvgRowSize="913" EstimateCPU="1.68105" EstimateIO="130.748" EstimateRebinds="0" EstimateRewinds="0" EstimateRows="3.3163" LogicalOp="Clustered Index Scan" NodeId="2" Parallel="false" PhysicalOp="Clustered Index Scan" EstimatedTotalSubtreeCost="132.429" TableCardinality="1528090">
                      <OutputList>
                        <ColumnReference Column="Chk1002" />
                        <ColumnReference Database="[LMS]" Schema="[dbo]" Table="[CEF]" Column="ID" />
                        <ColumnReference Database="[LMS]" Schema="[dbo]" Table="[CEF]" Column="TelEveID" />
                        <ColumnReference Database="[LMS]" Schema="[dbo]" Table="[CEF]" Column="TelDayID" />
                        <ColumnReference Database="[LMS]" Schema="[dbo]" Table="[CEF]" Column="TelMobID" />
                      </OutputList>
                      <RunTimeInformation>
                        <RunTimeCountersPerThread Thread="0" ActualRows="1" ActualEndOfScans="1" ActualExecutions="1" />
                      </RunTimeInformation>
                      <IndexScan Ordered="true" ScanDirection="BACKWARD" ForcedIndex="false" ForceSeek="false" NoExpandHint="false">
                        <DefinedValues>
                          <DefinedValue>
                            <ColumnReference Column="Chk1002" />
                          </DefinedValue>
                          <DefinedValue>
                            <ColumnReference Database="[LMS]" Schema="[dbo]" Table="[CEF]" Column="ID" />
                          </DefinedValue>
                          <DefinedValue>
                            <ColumnReference Database="[LMS]" Schema="[dbo]" Table="[CEF]" Column="TelEveID" />
                          </DefinedValue>
                          <DefinedValue>
                            <ColumnReference Database="[LMS]" Schema="[dbo]" Table="[CEF]" Column="TelDayID" />
                          </DefinedValue>
                          <DefinedValue>
                            <ColumnReference Database="[LMS]" Schema="[dbo]" Table="[CEF]" Column="TelMobID" />
                          </DefinedValue>
                        </DefinedValues>
                        <Object Database="[LMS]" Schema="[dbo]" Table="[CEF]" Index="[PK_CEF]" IndexKind="Clustered" />
                        <Predicate>
                          <ScalarOperator ScalarString="[LMS].[dbo].[CEF].[TelEveID]='+44xxxx' OR [LMS].[dbo].[CEF].[TelDayID]='+44xxxx' OR [LMS].[dbo].[CEF].[TelMobID]='+44xxxx'">
                            <Logical Operation="OR">
                              <ScalarOperator>
                                <Compare CompareOp="EQ">
                                  <ScalarOperator>
                                    <Identifier>
                                      <ColumnReference Database="[LMS]" Schema="[dbo]" Table="[CEF]" Column="TelEveID" />
                                    </Identifier>
                                  </ScalarOperator>
                                  <ScalarOperator>
                                    <Const ConstValue="'+44xxxx'" />
                                  </ScalarOperator>
                                </Compare>
                              </ScalarOperator>
                              <ScalarOperator>
                                <Compare CompareOp="EQ">
                                  <ScalarOperator>
                                    <Identifier>
                                      <ColumnReference Database="[LMS]" Schema="[dbo]" Table="[CEF]" Column="TelDayID" />
                                    </Identifier>
                                  </ScalarOperator>
                                  <ScalarOperator>
                                    <Const ConstValue="'+44xxxx'" />
                                  </ScalarOperator>
                                </Compare>
                              </ScalarOperator>
                              <ScalarOperator>
                                <Compare CompareOp="EQ">
                                  <ScalarOperator>
                                    <Identifier>
                                      <ColumnReference Database="[LMS]" Schema="[dbo]" Table="[CEF]" Column="TelMobID" />
                                    </Identifier>
                                  </ScalarOperator>
                                  <ScalarOperator>
                                    <Const ConstValue="'+44xxxx'" />
                                  </ScalarOperator>
                                </Compare>
                              </ScalarOperator>
                            </Logical>
                          </ScalarOperator>
                        </Predicate>
                      </IndexScan>
                    </RelOp>
                  </ComputeScalar>
                </RelOp>
              </Update>
            </RelOp>
          </QueryPlan>
        </StmtSimple>
      </Statements>
    </Batch>
  </BatchSequence>
</ShowPlanXML>

0 个答案:

没有答案