0

我想知道是否有可能优化这样的查询:

delete tx_txn_detail 
where transaction_id BETWEEN 1 AND 1000

其中 transaction_id 可以在 1 到 1000 之间或 1 到 1000000 之间取决于查询之一。

该表非常大(90+ 百万行),tran_id 被索引,用户始终访问数据库,它应该与 SQL Server 2000/2005/2008 兼容。

附上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.5069.00" xmlns="http://schemas.microsoft.com/sqlserver/2004/07/showplan">
  <BatchSequence>
    <Batch>
      <Statements>
        <StmtSimple StatementCompId="4" StatementEstRows="1" StatementId="1" StatementOptmLevel="TRIVIAL" StatementSubTreeCost="0.0232852" StatementText="DELETE [tx_txn_detail]  WHERE [transaction_id]&gt;=@1 AND [transaction_id]&lt;=@2" StatementType="DELETE">
          <StatementSetOptions ANSI_NULLS="false" ANSI_PADDING="false" ANSI_WARNINGS="false" ARITHABORT="true" CONCAT_NULL_YIELDS_NULL="false" NUMERIC_ROUNDABORT="false" QUOTED_IDENTIFIER="false" />
          <QueryPlan DegreeOfParallelism="1" CachedPlanSize="15" CompileTime="0" CompileCPU="0" CompileMemory="128">
            <RelOp AvgRowSize="9" EstimateCPU="2E-06" EstimateIO="0.02" EstimateRebinds="0" EstimateRewinds="0" EstimateRows="1" LogicalOp="Delete" NodeId="0" Parallel="false" PhysicalOp="Table Delete" EstimatedTotalSubtreeCost="0.0232852">
              <OutputList />
              <RunTimeInformation>
                <RunTimeCountersPerThread Thread="0" ActualRows="615" ActualEndOfScans="1" ActualExecutions="1" />
              </RunTimeInformation>
              <Update>
                <Object Database="[lty_uae]" Schema="[dbo]" Table="[tx_txn_detail]" />
                <Object Database="[lty_uae]" Schema="[dbo]" Table="[tx_txn_detail]" Index="[tx_txn_detail_PK_txn_seqid]" />
                <RelOp AvgRowSize="15" EstimateCPU="1E-07" EstimateIO="0" EstimateRebinds="0" EstimateRewinds="0" EstimateRows="1" LogicalOp="Top" NodeId="1" Parallel="false" PhysicalOp="Top" EstimatedTotalSubtreeCost="0.0032832">
                  <OutputList>
                    <ColumnReference Column="Bmk1000" />
                  </OutputList>
                  <RunTimeInformation>
                    <RunTimeCountersPerThread Thread="0" ActualRows="615" ActualEndOfScans="1" ActualExecutions="1" />
                  </RunTimeInformation>
                  <Top RowCount="true" IsPercent="false" WithTies="false">
                    <TopExpression>
                      <ScalarOperator ScalarString="(0)">
                        <Const ConstValue="(0)" />
                      </ScalarOperator>
                    </TopExpression>
                    <RelOp AvgRowSize="15" EstimateCPU="0.0001581" EstimateIO="0.003125" EstimateRebinds="0" EstimateRewinds="0" EstimateRows="1" LogicalOp="Index Seek" NodeId="2" Parallel="false" PhysicalOp="Index Seek" EstimatedTotalSubtreeCost="0.0032831">
                      <OutputList>
                        <ColumnReference Column="Bmk1000" />
                      </OutputList>
                      <RunTimeInformation>
                        <RunTimeCountersPerThread Thread="0" ActualRows="615" ActualEndOfScans="1" ActualExecutions="1" />
                      </RunTimeInformation>
                      <IndexScan Ordered="true" ScanDirection="FORWARD" ForcedIndex="false" NoExpandHint="false">
                        <DefinedValues>
                          <DefinedValue>
                            <ColumnReference Column="Bmk1000" />
                          </DefinedValue>
                        </DefinedValues>
                        <Object Database="[lty_uae]" Schema="[dbo]" Table="[tx_txn_detail]" Index="[tx_txn_detail_PK_txn_seqid]" />
                        <SeekPredicates>
                          <SeekPredicate>
                            <StartRange ScanType="GE">
                              <RangeColumns>
                                <ColumnReference Database="[lty_uae]" Schema="[dbo]" Table="[tx_txn_detail]" Column="transaction_id" />
                              </RangeColumns>
                              <RangeExpressions>
                                <ScalarOperator ScalarString="CONVERT_IMPLICIT(decimal(15,0),[@1],0)">
                                  <Identifier>
                                    <ColumnReference Column="ConstExpr1008">
                                      <ScalarOperator>
                                        <Convert DataType="decimal" Precision="15" Scale="0" Style="0" Implicit="true">
                                          <ScalarOperator>
                                            <Identifier>
                                              <ColumnReference Column="@1" />
                                            </Identifier>
                                          </ScalarOperator>
                                        </Convert>
                                      </ScalarOperator>
                                    </ColumnReference>
                                  </Identifier>
                                </ScalarOperator>
                              </RangeExpressions>
                            </StartRange>
                            <EndRange ScanType="LE">
                              <RangeColumns>
                                <ColumnReference Database="[lty_uae]" Schema="[dbo]" Table="[tx_txn_detail]" Column="transaction_id" />
                              </RangeColumns>
                              <RangeExpressions>
                                <ScalarOperator ScalarString="CONVERT_IMPLICIT(decimal(15,0),[@2],0)">
                                  <Identifier>
                                    <ColumnReference Column="ConstExpr1009">
                                      <ScalarOperator>
                                        <Convert DataType="decimal" Precision="15" Scale="0" Style="0" Implicit="true">
                                          <ScalarOperator>
                                            <Identifier>
                                              <ColumnReference Column="@2" />
                                            </Identifier>
                                          </ScalarOperator>
                                        </Convert>
                                      </ScalarOperator>
                                    </ColumnReference>
                                  </Identifier>
                                </ScalarOperator>
                              </RangeExpressions>
                            </EndRange>
                          </SeekPredicate>
                        </SeekPredicates>
                      </IndexScan>
                    </RelOp>
                  </Top>
                </RelOp>
              </Update>
            </RelOp>
            <ParameterList>
              <ColumnReference Column="@2" ParameterCompiledValue="(1000)" ParameterRuntimeValue="(1000)" />
              <ColumnReference Column="@1" ParameterCompiledValue="(1)" ParameterRuntimeValue="(1)" />
            </ParameterList>
          </QueryPlan>
        </StmtSimple>
      </Statements>
    </Batch>
    <Batch>
      <Statements>
        <StmtSimple StatementCompId="5" StatementEstRows="1" StatementId="2" StatementOptmLevel="FULL" StatementOptmEarlyAbortReason="GoodEnoughPlanFound" StatementSubTreeCost="0.00657038" StatementText="SELECT * FROM [tx_txn_detail] WHERE [transaction_id]&gt;=@1 AND [transaction_id]&lt;=@2" 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 DegreeOfParallelism="1" CachedPlanSize="28" CompileTime="2" CompileCPU="2" CompileMemory="152">
            <RelOp AvgRowSize="117" EstimateCPU="4.18E-06" EstimateIO="0" EstimateRebinds="0" EstimateRewinds="0" EstimateRows="1" LogicalOp="Inner Join" NodeId="0" Parallel="false" PhysicalOp="Nested Loops" EstimatedTotalSubtreeCost="0.00657038">
              <OutputList>
                <ColumnReference Database="[lty_uae]" Schema="[dbo]" Table="[tx_txn_detail]" Column="transaction_id" />
                <ColumnReference Database="[lty_uae]" Schema="[dbo]" Table="[tx_txn_detail]" Column="seq_id" />
                <ColumnReference Database="[lty_uae]" Schema="[dbo]" Table="[tx_txn_detail]" Column="product_code" />
                <ColumnReference Database="[lty_uae]" Schema="[dbo]" Table="[tx_txn_detail]" Column="qty" />
                <ColumnReference Database="[lty_uae]" Schema="[dbo]" Table="[tx_txn_detail]" Column="value" />
                <ColumnReference Database="[lty_uae]" Schema="[dbo]" Table="[tx_txn_detail]" Column="bonus_pts" />
                <ColumnReference Database="[lty_uae]" Schema="[dbo]" Table="[tx_txn_detail]" Column="txn_sub_seqid" />
                <ColumnReference Database="[lty_uae]" Schema="[dbo]" Table="[tx_txn_detail]" Column="promotion_id" />
                <ColumnReference Database="[lty_uae]" Schema="[dbo]" Table="[tx_txn_detail]" Column="group_code" />
                <ColumnReference Database="[lty_uae]" Schema="[dbo]" Table="[tx_txn_detail]" Column="register_type" />
                <ColumnReference Database="[lty_uae]" Schema="[dbo]" Table="[tx_txn_detail]" Column="promotion_code" />
                <ColumnReference Database="[lty_uae]" Schema="[dbo]" Table="[tx_txn_detail]" Column="std_pts" />
              </OutputList>
              <RunTimeInformation>
                <RunTimeCountersPerThread Thread="0" ActualRows="615" ActualEndOfScans="1" ActualExecutions="1" />
              </RunTimeInformation>
              <NestedLoops Optimized="false">
                <OuterReferences>
                  <ColumnReference Column="Bmk1000" />
                </OuterReferences>
                <RelOp AvgRowSize="26" EstimateCPU="0.0001581" EstimateIO="0.003125" EstimateRebinds="0" EstimateRewinds="0" EstimateRows="1" LogicalOp="Index Seek" NodeId="1" Parallel="false" PhysicalOp="Index Seek" EstimatedTotalSubtreeCost="0.0032831">
                  <OutputList>
                    <ColumnReference Column="Bmk1000" />
                    <ColumnReference Database="[lty_uae]" Schema="[dbo]" Table="[tx_txn_detail]" Column="transaction_id" />
                    <ColumnReference Database="[lty_uae]" Schema="[dbo]" Table="[tx_txn_detail]" Column="seq_id" />
                  </OutputList>
                  <RunTimeInformation>
                    <RunTimeCountersPerThread Thread="0" ActualRows="615" ActualEndOfScans="1" ActualExecutions="1" />
                  </RunTimeInformation>
                  <IndexScan Ordered="true" ScanDirection="FORWARD" ForcedIndex="false" NoExpandHint="false">
                    <DefinedValues>
                      <DefinedValue>
                        <ColumnReference Column="Bmk1000" />
                      </DefinedValue>
                      <DefinedValue>
                        <ColumnReference Database="[lty_uae]" Schema="[dbo]" Table="[tx_txn_detail]" Column="transaction_id" />
                      </DefinedValue>
                      <DefinedValue>
                        <ColumnReference Database="[lty_uae]" Schema="[dbo]" Table="[tx_txn_detail]" Column="seq_id" />
                      </DefinedValue>
                    </DefinedValues>
                    <Object Database="[lty_uae]" Schema="[dbo]" Table="[tx_txn_detail]" Index="[tx_txn_detail_PK_txn_seqid]" />
                    <SeekPredicates>
                      <SeekPredicate>
                        <StartRange ScanType="GE">
                          <RangeColumns>
                            <ColumnReference Database="[lty_uae]" Schema="[dbo]" Table="[tx_txn_detail]" Column="transaction_id" />
                          </RangeColumns>
                          <RangeExpressions>
                            <ScalarOperator ScalarString="(1.)">
                              <Const ConstValue="(1.)" />
                            </ScalarOperator>
                          </RangeExpressions>
                        </StartRange>
                        <EndRange ScanType="LE">
                          <RangeColumns>
                            <ColumnReference Database="[lty_uae]" Schema="[dbo]" Table="[tx_txn_detail]" Column="transaction_id" />
                          </RangeColumns>
                          <RangeExpressions>
                            <ScalarOperator ScalarString="(1000.)">
                              <Const ConstValue="(1000.)" />
                            </ScalarOperator>
                          </RangeExpressions>
                        </EndRange>
                      </SeekPredicate>
                    </SeekPredicates>
                  </IndexScan>
                </RelOp>
                <RelOp AvgRowSize="106" EstimateCPU="0.0001581" EstimateIO="0.003125" EstimateRebinds="0" EstimateRewinds="0" EstimateRows="1" LogicalOp="RID Lookup" NodeId="3" Parallel="false" PhysicalOp="RID Lookup" EstimatedTotalSubtreeCost="0.0032831">
                  <OutputList>
                    <ColumnReference Database="[lty_uae]" Schema="[dbo]" Table="[tx_txn_detail]" Column="product_code" />
                    <ColumnReference Database="[lty_uae]" Schema="[dbo]" Table="[tx_txn_detail]" Column="qty" />
                    <ColumnReference Database="[lty_uae]" Schema="[dbo]" Table="[tx_txn_detail]" Column="value" />
                    <ColumnReference Database="[lty_uae]" Schema="[dbo]" Table="[tx_txn_detail]" Column="bonus_pts" />
                    <ColumnReference Database="[lty_uae]" Schema="[dbo]" Table="[tx_txn_detail]" Column="txn_sub_seqid" />
                    <ColumnReference Database="[lty_uae]" Schema="[dbo]" Table="[tx_txn_detail]" Column="promotion_id" />
                    <ColumnReference Database="[lty_uae]" Schema="[dbo]" Table="[tx_txn_detail]" Column="group_code" />
                    <ColumnReference Database="[lty_uae]" Schema="[dbo]" Table="[tx_txn_detail]" Column="register_type" />
                    <ColumnReference Database="[lty_uae]" Schema="[dbo]" Table="[tx_txn_detail]" Column="promotion_code" />
                    <ColumnReference Database="[lty_uae]" Schema="[dbo]" Table="[tx_txn_detail]" Column="std_pts" />
                  </OutputList>
                  <RunTimeInformation>
                    <RunTimeCountersPerThread Thread="0" ActualRows="615" ActualEndOfScans="0" ActualExecutions="615" />
                  </RunTimeInformation>
                  <IndexScan Lookup="true" Ordered="true" ScanDirection="FORWARD" ForcedIndex="false" NoExpandHint="false">
                    <DefinedValues>
                      <DefinedValue>
                        <ColumnReference Database="[lty_uae]" Schema="[dbo]" Table="[tx_txn_detail]" Column="product_code" />
                      </DefinedValue>
                      <DefinedValue>
                        <ColumnReference Database="[lty_uae]" Schema="[dbo]" Table="[tx_txn_detail]" Column="qty" />
                      </DefinedValue>
                      <DefinedValue>
                        <ColumnReference Database="[lty_uae]" Schema="[dbo]" Table="[tx_txn_detail]" Column="value" />
                      </DefinedValue>
                      <DefinedValue>
                        <ColumnReference Database="[lty_uae]" Schema="[dbo]" Table="[tx_txn_detail]" Column="bonus_pts" />
                      </DefinedValue>
                      <DefinedValue>
                        <ColumnReference Database="[lty_uae]" Schema="[dbo]" Table="[tx_txn_detail]" Column="txn_sub_seqid" />
                      </DefinedValue>
                      <DefinedValue>
                        <ColumnReference Database="[lty_uae]" Schema="[dbo]" Table="[tx_txn_detail]" Column="promotion_id" />
                      </DefinedValue>
                      <DefinedValue>
                        <ColumnReference Database="[lty_uae]" Schema="[dbo]" Table="[tx_txn_detail]" Column="group_code" />
                      </DefinedValue>
                      <DefinedValue>
                        <ColumnReference Database="[lty_uae]" Schema="[dbo]" Table="[tx_txn_detail]" Column="register_type" />
                      </DefinedValue>
                      <DefinedValue>
                        <ColumnReference Database="[lty_uae]" Schema="[dbo]" Table="[tx_txn_detail]" Column="promotion_code" />
                      </DefinedValue>
                      <DefinedValue>
                        <ColumnReference Database="[lty_uae]" Schema="[dbo]" Table="[tx_txn_detail]" Column="std_pts" />
                      </DefinedValue>
                    </DefinedValues>
                    <Object Database="[lty_uae]" Schema="[dbo]" Table="[tx_txn_detail]" TableReferenceId="-1" />
                    <SeekPredicates>
                      <SeekPredicate>
                        <Prefix ScanType="EQ">
                          <RangeColumns>
                            <ColumnReference Column="Bmk1000" />
                          </RangeColumns>
                          <RangeExpressions>
                            <ScalarOperator ScalarString="[Bmk1000]">
                              <Identifier>
                                <ColumnReference Column="Bmk1000" />
                              </Identifier>
                            </ScalarOperator>
                          </RangeExpressions>
                        </Prefix>
                      </SeekPredicate>
                    </SeekPredicates>
                  </IndexScan>
                </RelOp>
              </NestedLoops>
            </RelOp>
            <ParameterList>
              <ColumnReference Column="@2" ParameterCompiledValue="(1000)" ParameterRuntimeValue="(1000)" />
              <ColumnReference Column="@1" ParameterCompiledValue="(1)" ParameterRuntimeValue="(1)" />
            </ParameterList>
          </QueryPlan>
        </StmtSimple>
      </Statements>
    </Batch>
  </BatchSequence>
</ShowPlanXML>

如果你有任何想法;)

4

1 回答 1

1

糟糕的是它没有分区。那会很容易。

以下是我在需要防止阻塞时执行大删除的方法:

DECLARE @ROWCNT INT , @NUMROWS INT, @TOPNUM INT
SET @ROWCNT = 0
SET @NUMROWS = 0
SET @TOPNUM = 100000 --<--- Set this to the number of rows to delete per batch.

WHILE 1 = 1
BEGIN

  DELETE TOP (@TOPNUM) 
  FROM dbo.FactTable
  WHERE ID = 6

  SET @NUMROWS = @@ROWCOUNT
  SET @ROWCNT = @ROWCNT + @NUMROWS
  IF @NUMROWS = 0 BREAK

  -- A delay may help prevent locking/blocking if required.
  WAITFOR DELAY '00:00:03'
END

这从来没有给我带来阻塞问题,但是,在做一些研究来回答这个问题时,我遇到了这篇文章:http ://www.sqlsoldier.com/wp/sqlserver/sqluvldbweekarchivingandpurgingdata它指出“还有一个旁注: 简单地在 delete 语句中添加 TOP 不会最小化最初占用的锁数量。请不要这样做!! "

所以,也许我需要更新我自己的删除方法。也许这是一种解决方法:

DECLARE @ROWCNT INT , @NUMROWS INT, @TOPNUM INT, @LASTDELETED INT
declare @ToDeleteIDS table (id int)
declare @IDS table (id int)
SET @ROWCNT = 0
SET @NUMROWS = 0
SET @TOPNUM = 100000 --<--- Set this to the number of rows to delete per batch.

INSERT INTO @ToDeleteIDS(id)
SELECT transaction_id
FROM tx_txn_detail with (nolock)
where transaction_id BETWEEN 1 AND 1000

INSERT INTO @IDS(id)
  SELECT  TOP (@TOPNUM) id
  FROM @ToDeleteIDS
  ORDER BY ID ASC

WHILE 1 = 1
BEGIN

  DELETE detail
  FROM tx_txn_detail detail
  JOIN @IDS b on detail.transaction_id = b.id


  SET @NUMROWS = @@ROWCOUNT
  SET @ROWCNT = @ROWCNT + @NUMROWS
  IF @NUMROWS = 0 BREAK

  Select @LASTDELETED = MAX(id)
  from @IDS

  Delete @IDS

  INSERT INTO @IDS(id)
  SELECT  TOP (@TOPNUM) id
  FROM @ToDeleteIDS
  WHERE   ID > @LASTDELETED
  ORDER BY ID ASC


END

请注意,我尚未对此进行测试。只是一个想法。

于 2013-04-16T22:02:17.593 回答