Sql server SQL 2008游标性能缓慢-索引扫描/查找

Sql server SQL 2008游标性能缓慢-索引扫描/查找,sql-server,sql-server-2008,indexing,cursor,Sql Server,Sql Server 2008,Indexing,Cursor,在SQLServer2008中使用ADO驱动程序时(或者更确切地说,在使用驱动程序创建的特定sql游标时),我发现了一个有趣的“问题”。 我们要执行以下查询: SELECT ID, TelEveID, TelDayID, TelMobID, QualityFlag, WeekBegin FROM CEF WHERE (TelEveID = '+44xxxx') OR (TelDayID = '+44xxxxx') OR (TelMobID = '+44xxxx') ORDER BY ID D

在SQLServer2008中使用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;televid]、[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倍。如果我们看一下实际的执行计划,我们就可以看出差异的原因

游标完全省略现有索引,并使用索引扫描,而“直接查询”将三个“单独的”结果集合并到具有适当索引用法的最终结果集

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

有没有办法避免这种行为而不完全删除游标(因为在执行此操作的旧应用程序中不可能这样做)

谢谢

马丁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>