如何确保计数表的连续性?

时间:2012-08-29 17:06:27

标签: sql sql-server integrity

SQL For Smarties中,Joe Celko提供了Series表的ANSI SQL定义(在其他地方称为Tally或Numbers)。他的定义确保列中的值从1到最大值是唯一的,正的和连续的:

CREATE TABLE Series (
  seq INTEGER NOT NULL PRIMARY KEY,
  CONSTRAINT non_negative_nbr CHECK (seq > 0),
  CONSTRAINT numbers_are_complete CHECK ((SELECT COUNT(*) FROM Series) = (SELECT MAX(seq) FROM Series))
);

PRIMARY KEY声明确保了唯一性。约束non_negative_nbr确保了积极性。有了这两个约束,约束numbers_are_complete确保了连续性。

SQL Server不支持检查约束中的子查询。当我尝试创建Series表时,我收到如下错误:

Msg 1046, Level 15, State 1, Line 4
Subqueries are not allowed in this context. Only scalar expressions are allowed.
Msg 102, Level 15, State 1, Line 4
Incorrect syntax near ')'.

如果我删除不受支持的约束numbers_are_complete,我就会留下这个定义:

CREATE TABLE Series (
  seq INTEGER NOT NULL PRIMARY KEY,
  CONSTRAINT non_negative_nbr CHECK (seq > 0)
);

当我尝试创建此版本的系列时,它会成功:

Command(s) completed successfully.

此版本的系列较弱,因为它不会强制表中数字的连续性。

为了证明这一点,首先我必须填充表格。我已经改编了Itzik Ben-Gan在他的文章“Virtual Auxiliary Table of Numbers”中描述的一种技术,可以有效地为65,536行做到这一点:

WITH
N0(_) AS (SELECT NULL UNION ALL SELECT NULL),
N1(_) AS (SELECT NULL FROM N0 AS L CROSS JOIN N0 AS R),
N2(_) AS (SELECT NULL FROM N1 AS L CROSS JOIN N1 AS R),
N3(_) AS (SELECT NULL FROM N2 AS L CROSS JOIN N2 AS R),
N4(_) AS (SELECT NULL FROM N3 AS L CROSS JOIN N3 AS R)
INSERT INTO Series (
  seq
)
SELECT
  ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS n
FROM N4;

查询产生如下输出:

(65536 row(s) affected)

现在我可以从这样的表中选择产生65,536行:

SELECT seq
FROM Series;

我已截断结果集,但看起来像这样:

seq
1
2
...
65535
65536

自己检查,你会发现区间[1,65536]中的每个数字都在结果集中。该系列是连续的。

但是我可以通过删除任何不是该范围的端点的行来打破连续性:

DELETE FROM Series
WHERE seq = 25788;

如果强制执行邻接,则此语句会引发错误,但会成功:

(1 row(s) affected)

人类很难通过视觉检查找到缺失值。在遇到麻烦之前,他们必须首先怀疑价值缺失。由于这些原因,篡改系列数据是一种简单的方法,可以将细微的错误引入依赖于Series表连续的SQL Server应用程序。

假设用户编写了一个查询,该查询从Sequence读取以枚举来自其他源的行。在我被篡改之后,该查询现在会在某个值周围产生不正确的结果 - 到第25,788行,一切都被一个人关闭。

可以编写一个查询来检测Series表中的缺失值,但是如何约束表以便丢失值是不可能的?

3 个答案:

答案 0 :(得分:4)

我有三个可能的建议:


(1)将您的数字表设为只读(例如拒绝更新/插入/删除)。为什么要从这张表中删除,是吗?你的应用当然不应该这样做,你的用户也不应该手动这样做。按下“按钮做什么?”的用户不需要所有这些检查约束。按钮,只需删除按钮即可。

DENY DELETE ON dbo.Serial TO [your_app_user];
-- repeat for individual users/roles

(2)更容易创建一个而不是触发器来防止删除:

CREATE TRIGGER dbo.LeaveMyNumbersAlone
ON dbo.Serial
INSTEAD OF DELETE
AS
BEGIN
  SET NOCOUNT ON;
  RAISERROR('Please leave my numbers table alone.', 11, 1);
END

是的,这可能会失败,但有人必须真正做到这一点。如果你雇用那些可能会这样做的人,并且信任他们对数据库的通用访问权,那么请保证这是他们计划做的最大的伤害。

是的,如果您删除/重新创建数字表或在其他地方实现数字表,您可能会忘记重新实现触发器。但是你可能也会忘记你手动做的任何事情来处理差距。


(3)如果您愿意动态获取数字,则可以完全避免使用数字表。我使用目录视图,如sys.all_columns和sys.all_objects,具体取决于我需要多少个数字:

;WITH n AS (SELECT TOP (10000) n FROM 
  (SELECT n = ROW_NUMBER() OVER
    (ORDER BY s1.[object_id])
    FROM sys.all_objects AS s1
    CROSS JOIN sys.all_objects AS s2
  ) AS x ORDER BY n
)
SELECT n FROM n ORDER BY n; -- look ma, no gaps!

如果您只需要100行,则可以使用其中一个没有交叉连接的视图;如果您需要更多,可以添加更多视图。不是试图将你从数字表中推开,但这会让你受到限制,例如:(a)在每个单独的实例上建立一个数字表;(b)在哲学上反对这样的事情的人(我在我的生涯)。


顺便说一句,这确实应该在产品中。请在以下Connect项目中投票并说明实际业务用例:

http://connect.microsoft.com/SQLServer/feedback/details/258733/add-a-built-in-table-of-numbers

答案 1 :(得分:2)

解决此问题的一种方法是用视图替换表。

此视图定义基于问题中引用的同一篇文章,最多可生成65,536个唯一,正面和连续的行:

CREATE VIEW SeriesView
AS
WITH
N0(_) AS (SELECT NULL UNION ALL SELECT NULL),
N1(_) AS (SELECT NULL FROM N0 AS L CROSS JOIN N0 AS R),
N2(_) AS (SELECT NULL FROM N1 AS L CROSS JOIN N1 AS R),
N3(_) AS (SELECT NULL FROM N2 AS L CROSS JOIN N2 AS R),
N4(_) AS (SELECT NULL FROM N3 AS L CROSS JOIN N3 AS R)
SELECT
    ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS seq
FROM N4;

通过这种方式,ROW_NUMBER函数始终在查询时生成行号。 ROW_NUMBER函数输出的值集是连续的,每个值都是唯一且正的。

如果您尝试从视图中删除:

DELETE FROM SeriesView
WHERE seq = 25788;

服务器将引发错误,因为视图不可更新:

Msg 4406, Level 16, State 1, Line 1
Update or insert of view or function 'SeriesView' failed because it 

包含派生或常量字段。

与将值存储在表中相比,我没有比较此技术的性能。在实践中,两者看起来都足够快,但我承认我还没有在生产中使用该视图。

从Series中选择的查询的性能调优可能会更加困难,因为只需从视图中选择就可以生成大量的执行计划。

只需比较这些执行计划的长度,以比较它们的明显复杂性:

这是通过从问题中的表中选择而生成的执行计划:

<?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.1" Build="10.0.5500.0" xmlns="http://schemas.microsoft.com/sqlserver/2004/07/showplan">
    <BatchSequence>
        <Batch>
            <Statements>
                <StmtSimple StatementCompId="1" StatementEstRows="65535" StatementId="1" StatementOptmLevel="TRIVIAL" StatementSubTreeCost="0.153148" StatementText="SELECT seq&#xD;&#xA;FROM Series;" StatementType="SELECT" QueryHash="0x5765DD2692E59AB9" QueryPlanHash="0x598E82F24F85C8B9">
                    <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="1" CachedPlanSize="8" CompileTime="0" CompileCPU="0" CompileMemory="80">
                        <RelOp AvgRowSize="11" EstimateCPU="0.0722455" EstimateIO="0.0809028" EstimateRebinds="0" EstimateRewinds="0" EstimateRows="65535" LogicalOp="Clustered Index Scan" NodeId="0" Parallel="false" PhysicalOp="Clustered Index Scan" EstimatedTotalSubtreeCost="0.153148" TableCardinality="65535">
                            <OutputList>
                                <ColumnReference Database="[tempdb]" Schema="[dbo]" Table="[Series]" Column="seq" />
                            </OutputList>
                            <RunTimeInformation>
                                <RunTimeCountersPerThread Thread="0" ActualRows="65535" ActualEndOfScans="1" ActualExecutions="1" />
                            </RunTimeInformation>
                            <IndexScan Ordered="false" ForcedIndex="false" NoExpandHint="false">
                                <DefinedValues>
                                    <DefinedValue>
                                        <ColumnReference Database="[tempdb]" Schema="[dbo]" Table="[Series]" Column="seq" />
                                    </DefinedValue>
                                </DefinedValues>
                                <Object Database="[tempdb]" Schema="[dbo]" Table="[Series]" Index="[PK__Series__DDDFBCBE0F975522]" IndexKind="Clustered" />
                            </IndexScan>
                        </RelOp>
                    </QueryPlan>
                </StmtSimple>
            </Statements>
        </Batch>
    </BatchSequence>
</ShowPlanXML>

这是通过从我的答案中的视图中选择而生成的执行计划:

<?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.1" Build="10.0.5500.0" xmlns="http://schemas.microsoft.com/sqlserver/2004/07/showplan">
    <BatchSequence>
        <Batch>
            <Statements>
                <StmtSimple StatementCompId="1" StatementEstRows="65536" StatementId="1" StatementOptmLevel="FULL" StatementOptmEarlyAbortReason="TimeOut" StatementSubTreeCost="0.692044" StatementText="SELECT seq&#xD;&#xA;FROM SeriesView;" StatementType="SELECT" QueryHash="0xD7D3DE2C825E3F56" QueryPlanHash="0x927D671566369AAC">
                    <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="1" CachedPlanSize="32" CompileTime="6" CompileCPU="6" CompileMemory="680">
                        <RelOp AvgRowSize="15" EstimateCPU="0.00524288" EstimateIO="0" EstimateRebinds="0" EstimateRewinds="0" EstimateRows="65536" LogicalOp="Compute Scalar" NodeId="0" Parallel="false" PhysicalOp="Sequence Project" EstimatedTotalSubtreeCost="0.692044">
                            <OutputList>
                                <ColumnReference Column="Expr1065" />
                            </OutputList>
                            <RunTimeInformation>
                                <RunTimeCountersPerThread Thread="0" ActualRows="65536" ActualEndOfScans="1" ActualExecutions="1" />
                            </RunTimeInformation>
                            <SequenceProject>
                                <DefinedValues>
                                    <DefinedValue>
                                        <ColumnReference Column="Expr1065" />
                                        <ScalarOperator ScalarString="row_number">
                                            <Sequence FunctionName="row_number" />
                                        </ScalarOperator>
                                    </DefinedValue>
                                </DefinedValues>
                                <RelOp AvgRowSize="15" EstimateCPU="0.00131072" EstimateIO="0" EstimateRebinds="0" EstimateRewinds="0" EstimateRows="65536" LogicalOp="Segment" NodeId="1" Parallel="false" PhysicalOp="Segment" EstimatedTotalSubtreeCost="0.686801">
                                    <OutputList>
                                        <ColumnReference Column="Expr1064" />
                                        <ColumnReference Column="Segment1066" />
                                    </OutputList>
                                    <RunTimeInformation>
                                        <RunTimeCountersPerThread Thread="0" ActualRows="65536" ActualEndOfScans="1" ActualExecutions="1" />
                                    </RunTimeInformation>
                                    <Segment>
                                        <GroupBy />
                                        <SegmentColumn>
                                            <ColumnReference Column="Segment1066" />
                                        </SegmentColumn>
                                        <RelOp AvgRowSize="11" EstimateCPU="0.0065536" EstimateIO="0" EstimateRebinds="0" EstimateRewinds="0" EstimateRows="65536" LogicalOp="Compute Scalar" NodeId="2" Parallel="false" PhysicalOp="Compute Scalar" EstimatedTotalSubtreeCost="0.68549">
                                            <OutputList>
                                                <ColumnReference Column="Expr1064" />
                                            </OutputList>
                                            <ComputeScalar>
                                                <DefinedValues>
                                                    <DefinedValue>
                                                        <ColumnReference Column="Expr1064" />
                                                        <ScalarOperator ScalarString="NULL">
                                                            <Const ConstValue="NULL" />
                                                        </ScalarOperator>
                                                    </DefinedValue>
                                                </DefinedValues>
                                                <RelOp AvgRowSize="9" EstimateCPU="0.27394" EstimateIO="0" EstimateRebinds="0" EstimateRewinds="0" EstimateRows="65536" LogicalOp="Inner Join" NodeId="3" Parallel="false" PhysicalOp="Nested Loops" EstimatedTotalSubtreeCost="0.678937">
                                                    <OutputList />
                                                    <Warnings NoJoinPredicate="true" />
                                                    <RunTimeInformation>
                                                        <RunTimeCountersPerThread Thread="0" ActualRows="65536" ActualEndOfScans="1" ActualExecutions="1" />
                                                    </RunTimeInformation>
                                                    <NestedLoops Optimized="false">
                                                        <RelOp AvgRowSize="9" EstimateCPU="0.13697" EstimateIO="0" EstimateRebinds="0" EstimateRewinds="0" EstimateRows="32768" LogicalOp="Inner Join" NodeId="4" Parallel="false" PhysicalOp="Nested Loops" EstimatedTotalSubtreeCost="0.33946">
                                                            <OutputList />
                                                            <Warnings NoJoinPredicate="true" />
                                                            <RunTimeInformation>
                                                                <RunTimeCountersPerThread Thread="0" ActualRows="32768" ActualEndOfScans="1" ActualExecutions="1" />
                                                            </RunTimeInformation>
                                                            <NestedLoops Optimized="false">
                                                                <RelOp AvgRowSize="9" EstimateCPU="0.0684851" EstimateIO="0" EstimateRebinds="0" EstimateRewinds="0" EstimateRows="16384" LogicalOp="Inner Join" NodeId="5" Parallel="false" PhysicalOp="Nested Loops" EstimatedTotalSubtreeCost="0.169722">
                                                                    <OutputList />
                                                                    <Warnings NoJoinPredicate="true" />
                                                                    <RunTimeInformation>
                                                                        <RunTimeCountersPerThread Thread="0" ActualRows="16384" ActualEndOfScans="1" ActualExecutions="1" />
                                                                    </RunTimeInformation>
                                                                    <NestedLoops Optimized="false">
                                                                        <RelOp AvgRowSize="9" EstimateCPU="0.0342426" EstimateIO="0" EstimateRebinds="0" EstimateRewinds="0" EstimateRows="8192" LogicalOp="Inner Join" NodeId="6" Parallel="false" PhysicalOp="Nested Loops" EstimatedTotalSubtreeCost="0.0848524">
                                                                            <OutputList />
                                                                            <Warnings NoJoinPredicate="true" />
                                                                            <RunTimeInformation>
                                                                                <RunTimeCountersPerThread Thread="0" ActualRows="8192" ActualEndOfScans="1" ActualExecutions="1" />
                                                                            </RunTimeInformation>
                                                                            <NestedLoops Optimized="false">
                                                                                <RelOp AvgRowSize="9" EstimateCPU="0.0171213" EstimateIO="0" EstimateRebinds="0" EstimateRewinds="0" EstimateRows="4096" LogicalOp="Inner Join" NodeId="7" Parallel="false" PhysicalOp="Nested Loops" EstimatedTotalSubtreeCost="0.0424177">
                                                                                    <OutputList />
                                                                                    <Warnings NoJoinPredicate="true" />
                                                                                    <RunTimeInformation>
                                                                                        <RunTimeCountersPerThread Thread="0" ActualRows="4096" ActualEndOfScans="1" ActualExecutions="1" />
                                                                                    </RunTimeInformation>
                                                                                    <NestedLoops Optimized="false">
                                                                                        <RelOp AvgRowSize="9" EstimateCPU="0.00856064" EstimateIO="0" EstimateRebinds="0" EstimateRewinds="0" EstimateRows="2048" LogicalOp="Inner Join" NodeId="8" Parallel="false" PhysicalOp="Nested Loops" EstimatedTotalSubtreeCost="0.0212003">
                                                                                            <OutputList />
                                                                                            <Warnings NoJoinPredicate="true" />
                                                                                            <RunTimeInformation>
                                                                                                <RunTimeCountersPerThread Thread="0" ActualRows="2048" ActualEndOfScans="1" ActualExecutions="1" />
                                                                                            </RunTimeInformation>
                                                                                            <NestedLoops Optimized="false">
                                                                                                <RelOp AvgRowSize="9" EstimateCPU="0.00428032" EstimateIO="0" EstimateRebinds="0" EstimateRewinds="0" EstimateRows="1024" LogicalOp="Inner Join" NodeId="9" Parallel="false" PhysicalOp="Nested Loops" EstimatedTotalSubtreeCost="0.0105915">
                                                                                                    <OutputList />
                                                                                                    <Warnings NoJoinPredicate="true" />
                                                                                                    <RunTimeInformation>
                                                                                                        <RunTimeCountersPerThread Thread="0" ActualRows="1024" ActualEndOfScans="1" ActualExecutions="1" />
                                                                                                    </RunTimeInformation>
                                                                                                    <NestedLoops Optimized="false">
                                                                                                        <RelOp AvgRowSize="9" EstimateCPU="0.00214016" EstimateIO="0" EstimateRebinds="0" EstimateRewinds="0" EstimateRows="512" LogicalOp="Inner Join" NodeId="10" Parallel="false" PhysicalOp="Nested Loops" EstimatedTotalSubtreeCost="0.00528701">
                                                                                                            <OutputList />
                                                                                                            <Warnings NoJoinPredicate="true" />
                                                                                                            <RunTimeInformation>
                                                                                                                <RunTimeCountersPerThread Thread="0" ActualRows="512" ActualEndOfScans="1" ActualExecutions="1" />
                                                                                                            </RunTimeInformation>
                                                                                                            <NestedLoops Optimized="false">
                                                                                                                <RelOp AvgRowSize="9" EstimateCPU="0.00107008" EstimateIO="0" EstimateRebinds="0" EstimateRewinds="0" EstimateRows="256" LogicalOp="Inner Join" NodeId="11" Parallel="false" PhysicalOp="Nested Loops" EstimatedTotalSubtreeCost="0.0026347">
                                                                                                                    <OutputList />
                                                                                                                    <Warnings NoJoinPredicate="true" />
                                                                                                                    <RunTimeInformation>
                                                                                                                        <RunTimeCountersPerThread Thread="0" ActualRows="256" ActualEndOfScans="1" ActualExecutions="1" />
                                                                                                                    </RunTimeInformation>
                                                                                                                    <NestedLoops Optimized="false">
                                                                                                                        <RelOp AvgRowSize="9" EstimateCPU="0.00053504" EstimateIO="0" EstimateRebinds="0" EstimateRewinds="0" EstimateRows="128" LogicalOp="Inner Join" NodeId="12" Parallel="false" PhysicalOp="Nested Loops" EstimatedTotalSubtreeCost="0.00130846">
                                                                                                                            <OutputList />
                                                                                                                            <Warnings NoJoinPredicate="true" />
                                                                                                                            <RunTimeInformation>
                                                                                                                                <RunTimeCountersPerThread Thread="0" ActualRows="128" ActualEndOfScans="1" ActualExecutions="1" />
                                                                                                                            </RunTimeInformation>
                                                                                                                            <NestedLoops Optimized="false">
                                                                                                                                <RelOp AvgRowSize="9" EstimateCPU="0.00026752" EstimateIO="0" EstimateRebinds="0" EstimateRewinds="0" EstimateRows="64" LogicalOp="Inner Join" NodeId="13" Parallel="false" PhysicalOp="Nested Loops" EstimatedTotalSubtreeCost="0.000645262">
                                                                                                                                    <OutputList />
                                                                                                                                    <Warnings NoJoinPredicate="true" />
                                                                                                                                    <RunTimeInformation>
                                                                                                                                        <RunTimeCountersPerThread Thread="0" ActualRows="64" ActualEndOfScans="1" ActualExecutions="1" />
                                                                                                                                    </RunTimeInformation>
                                                                                                                                    <NestedLoops Optimized="false">
                                                                                                                                        <RelOp AvgRowSize="9" EstimateCPU="0.00013376" EstimateIO="0" EstimateRebinds="0" EstimateRewinds="0" EstimateRows="32" LogicalOp="Inner Join" NodeId="14" Parallel="false" PhysicalOp="Nested Loops" EstimatedTotalSubtreeCost="0.000313585">
                                                                                                                                            <OutputList />
                                                                                                                                            <Warnings NoJoinPredicate="true" />
                                                                                                                                            <RunTimeInformation>
                                                                                                                                                <RunTimeCountersPerThread Thread="0" ActualRows="32" ActualEndOfScans="1" ActualExecutions="1" />
                                                                                                                                            </RunTimeInformation>
                                                                                                                                            <NestedLoops Optimized="false">
                                                                                                                                                <RelOp AvgRowSize="9" EstimateCPU="6.688E-05" EstimateIO="0" EstimateRebinds="0" EstimateRewinds="0" EstimateRows="16" LogicalOp="Inner Join" NodeId="15" Parallel="false" PhysicalOp="Nested Loops" EstimatedTotalSubtreeCost="0.000147668">
                                                                                                                                                    <OutputList />
                                                                                                                                                    <Warnings NoJoinPredicate="true" />
                                                                                                                                                    <RunTimeInformation>
                                                                                                                                                        <RunTimeCountersPerThread Thread="0" ActualRows="16" ActualEndOfScans="1" ActualExecutions="1" />
                                                                                                                                                    </RunTimeInformation>
                                                                                                                                                    <NestedLoops Optimized="false">
                                                                                                                                                        <RelOp AvgRowSize="9" EstimateCPU="3.344E-05" EstimateIO="0" EstimateRebinds="0" EstimateRewinds="0" EstimateRows="8" LogicalOp="Inner Join" NodeId="16" Parallel="false" PhysicalOp="Nested Loops" EstimatedTotalSubtreeCost="6.4631E-05">
                                                                                                                                                            <OutputList />
                                                                                                                                                            <Warnings NoJoinPredicate="true" />
                                                                                                                                                            <RunTimeInformation>
                                                                                                                                                                <RunTimeCountersPerThread Thread="0" ActualRows="8" ActualEndOfScans="1" ActualExecutions="1" />
                                                                                                                                                            </RunTimeInformation>
                                                                                                                                                            <NestedLoops Optimized="false">
                                                                                                                                                                <RelOp AvgRowSize="9" EstimateCPU="1.672E-05" EstimateIO="0" EstimateRebinds="0" EstimateRewinds="0" EstimateRows="4" LogicalOp="Inner Join" NodeId="17" Parallel="false" PhysicalOp="Nested Loops" EstimatedTotalSubtreeCost="2.3034E-05">
                                                                                                                                                                    <OutputList />
                                                                                                                                                                    <Warnings NoJoinPredicate="true" />
                                                                                                                                                                    <RunTimeInformation>
                                                                                                                                                                        <RunTimeCountersPerThread Thread="0" ActualRows="4" ActualEndOfScans="1" ActualExecutions="1" />
                                                                                                                                                                    </RunTimeInformation>
                                                                                                                                                                    <NestedLoops Optimized="false">
                                                                                                                                                                        <RelOp AvgRowSize="9" EstimateCPU="2.157E-06" EstimateIO="0" EstimateRebinds="0" EstimateRewinds="0" EstimateRows="2" LogicalOp="Constant Scan" NodeId="18" Parallel="false" PhysicalOp="Constant Scan" EstimatedTotalSubtreeCost="2.157E-06">
                                                                                                                                                                            <OutputList />
                                                                                                                                                                            <RunTimeInformation>
                                                                                                                                                                                <RunTimeCountersPerThread Thread="0" ActualRows="2" ActualEndOfScans="1" ActualExecutions="1" />
                                                                                                                                                                            </RunTimeInformation>
                                                                                                                                                                            <ConstantScan />
                                                                                                                                                                        </RelOp>
                                                                                                                                                                        <RelOp AvgRowSize="9" EstimateCPU="2.157E-06" EstimateIO="0" EstimateRebinds="0" EstimateRewinds="1" EstimateRows="2" LogicalOp="Constant Scan" NodeId="19" Parallel="false" PhysicalOp="Constant Scan" EstimatedTotalSubtreeCost="4.157E-06">
                                                                                                                                                                            <OutputList />
                                                                                                                                                                            <RunTimeInformation>
                                                                                                                                                                                <RunTimeCountersPerThread Thread="0" ActualRows="4" ActualEndOfScans="2" ActualExecutions="2" />
                                                                                                                                                                            </RunTimeInformation>
                                                                                                                                                                            <ConstantScan />
                                                                                                                                                                        </RelOp>
                                                                                                                                                                    </NestedLoops>
                                                                                                                                                                </RelOp>
                                                                                                                                                                <RelOp AvgRowSize="9" EstimateCPU="2.157E-06" EstimateIO="0" EstimateRebinds="0" EstimateRewinds="1" EstimateRows="2" LogicalOp="Constant Scan" NodeId="20" Parallel="false" PhysicalOp="Constant Scan" EstimatedTotalSubtreeCost="4.157E-06">
                                                                                                                                                                    <OutputList />
                                                                                                                                                                    <RunTimeInformation>
                                                                                                                                                                        <RunTimeCountersPerThread Thread="0" ActualRows="8" ActualEndOfScans="4" ActualExecutions="4" />
                                                                                                                                                                    </RunTimeInformation>
                                                                                                                                                                    <ConstantScan />
                                                                                                                                                                </RelOp>
                                                                                                                                                            </NestedLoops>
                                                                                                                                                        </RelOp>
                                                                                                                                                        <RelOp AvgRowSize="9" EstimateCPU="2.157E-06" EstimateIO="0" EstimateRebinds="0" EstimateRewinds="1" EstimateRows="2" LogicalOp="Constant Scan" NodeId="21" Parallel="false" PhysicalOp="Constant Scan" EstimatedTotalSubtreeCost="4.157E-06">
                                                                                                                                                            <OutputList />
                                                                                                                                                            <RunTimeInformation>
                                                                                                                                                                <RunTimeCountersPerThread Thread="0" ActualRows="16" ActualEndOfScans="8" ActualExecutions="8" />
                                                                                                                                                            </RunTimeInformation>
                                                                                                                                                            <ConstantScan />
                                                                                                                                                        </RelOp>
                                                                                                                                                    </NestedLoops>
                                                                                                                                                </RelOp>
                                                                                                                                                <RelOp AvgRowSize="9" EstimateCPU="2.157E-06" EstimateIO="0" EstimateRebinds="0" EstimateRewinds="15" EstimateRows="2" LogicalOp="Constant Scan" NodeId="22" Parallel="false" PhysicalOp="Constant Scan" EstimatedTotalSubtreeCost="3.2157E-05">
                                                                                                                                                    <OutputList />
                                                                                                                                                    <RunTimeInformation>
                                                                                                                                                        <RunTimeCountersPerThread Thread="0" ActualRows="32" ActualEndOfScans="16" ActualExecutions="16" />
                                                                                                                                                    </RunTimeInformation>
                                                                                                                                                    <ConstantScan />
                                                                                                                                                </RelOp>
                                                                                                                                            </NestedLoops>
                                                                                                                                        </RelOp>
                                                                                                                                        <RelOp AvgRowSize="9" EstimateCPU="2.157E-06" EstimateIO="0" EstimateRebinds="0" EstimateRewinds="15" EstimateRows="2" LogicalOp="Constant Scan" NodeId="23" Parallel="false" PhysicalOp="Constant Scan" EstimatedTotalSubtreeCost="3.2157E-05">
                                                                                                                                            <OutputList />
                                                                                                                                            <RunTimeInformation>
                                                                                                                                                <RunTimeCountersPerThread Thread="0" ActualRows="64" ActualEndOfScans="32" ActualExecutions="32" />
                                                                                                                                            </RunTimeInformation>
                                                                                                                                            <ConstantScan />
                                                                                                                                        </RelOp>
                                                                                                                                    </NestedLoops>
                                                                                                                                </RelOp>
                                                                                                                                <RelOp AvgRowSize="9" EstimateCPU="2.157E-06" EstimateIO="0" EstimateRebinds="0" EstimateRewinds="15" EstimateRows="2" LogicalOp="Constant Scan" NodeId="24" Parallel="false" PhysicalOp="Constant Scan" EstimatedTotalSubtreeCost="3.2157E-05">
                                                                                                                                    <OutputList />
                                                                                                                                    <RunTimeInformation>
                                                                                                                                        <RunTimeCountersPerThread Thread="0" ActualRows="128" ActualEndOfScans="64" ActualExecutions="64" />
                                                                                                                                    </RunTimeInformation>
                                                                                                                                    <ConstantScan />
                                                                                                                                </RelOp>
                                                                                                                            </NestedLoops>
                                                                                                                        </RelOp>
                                                                                                                        <RelOp AvgRowSize="9" EstimateCPU="2.157E-06" EstimateIO="0" EstimateRebinds="0" EstimateRewinds="15" EstimateRows="2" LogicalOp="Constant Scan" NodeId="25" Parallel="false" PhysicalOp="Constant Scan" EstimatedTotalSubtreeCost="3.2157E-05">
                                                                                                                            <OutputList />
                                                                                                                            <RunTimeInformation>
                                                                                                                                <RunTimeCountersPerThread Thread="0" ActualRows="256" ActualEndOfScans="128" ActualExecutions="128" />
                                                                                                                            </RunTimeInformation>
                                                                                                                            <ConstantScan />
                                                                                                                        </RelOp>
                                                                                                                    </NestedLoops>
                                                                                                                </RelOp>
                                                                                                                <RelOp AvgRowSize="9" EstimateCPU="2.157E-06" EstimateIO="0" EstimateRebinds="0" EstimateRewinds="255" EstimateRows="2" LogicalOp="Constant Scan" NodeId="26" Parallel="false" PhysicalOp="Constant Scan" EstimatedTotalSubtreeCost="0.000512157">
                                                                                                                    <OutputList />
                                                                                                                    <RunTimeInformation>
                                                                                                                        <RunTimeCountersPerThread Thread="0" ActualRows="512" ActualEndOfScans="256" ActualExecutions="256" />
                                                                                                                    </RunTimeInformation>
                                                                                                                    <ConstantScan />
                                                                                                                </RelOp>
                                                                                                            </NestedLoops>
                                                                                                        </RelOp>
                                                                                                        <RelOp AvgRowSize="9" EstimateCPU="2.157E-06" EstimateIO="0" EstimateRebinds="0" EstimateRewinds="255" EstimateRows="2" LogicalOp="Constant Scan" NodeId="27" Parallel="false" PhysicalOp="Constant Scan" EstimatedTotalSubtreeCost="0.000512157">
                                                                                                            <OutputList />
                                                                                                            <RunTimeInformation>
                                                                                                                <RunTimeCountersPerThread Thread="0" ActualRows="1024" ActualEndOfScans="512" ActualExecutions="512" />
                                                                                                            </RunTimeInformation>
                                                                                                            <ConstantScan />
                                                                                                        </RelOp>
                                                                                                    </NestedLoops>
                                                                                                </RelOp>
                                                                                                <RelOp AvgRowSize="9" EstimateCPU="2.157E-06" EstimateIO="0" EstimateRebinds="0" EstimateRewinds="255" EstimateRows="2" LogicalOp="Constant Scan" NodeId="28" Parallel="false" PhysicalOp="Constant Scan" EstimatedTotalSubtreeCost="0.000512157">
                                                                                                    <OutputList />
                                                                                                    <RunTimeInformation>
                                                                                                        <RunTimeCountersPerThread Thread="0" ActualRows="2048" ActualEndOfScans="1024" ActualExecutions="1024" />
                                                                                                    </RunTimeInformation>
                                                                                                    <ConstantScan />
                                                                                                </RelOp>
                                                                                            </NestedLoops>
                                                                                        </RelOp>
                                                                                        <RelOp AvgRowSize="9" EstimateCPU="2.157E-06" EstimateIO="0" EstimateRebinds="0" EstimateRewinds="255" EstimateRows="2" LogicalOp="Constant Scan" NodeId="29" Parallel="false" PhysicalOp="Constant Scan" EstimatedTotalSubtreeCost="0.000512157">
                                                                                            <OutputList />
                                                                                            <RunTimeInformation>
                                                                                                <RunTimeCountersPerThread Thread="0" ActualRows="4096" ActualEndOfScans="2048" ActualExecutions="2048" />
                                                                                            </RunTimeInformation>
                                                                                            <ConstantScan />
                                                                                        </RelOp>
                                                                                    </NestedLoops>
                                                                                </RelOp>
                                                                                <RelOp AvgRowSize="9" EstimateCPU="2.157E-06" EstimateIO="0" EstimateRebinds="0" EstimateRewinds="4095" EstimateRows="2" LogicalOp="Constant Scan" NodeId="30" Parallel="false" PhysicalOp="Constant Scan" EstimatedTotalSubtreeCost="0.00819216">
                                                                                    <OutputList />
                                                                                    <RunTimeInformation>
                                                                                        <RunTimeCountersPerThread Thread="0" ActualRows="8192" ActualEndOfScans="4096" ActualExecutions="4096" />
                                                                                    </RunTimeInformation>
                                                                                    <ConstantScan />
                                                                                </RelOp>
                                                                            </NestedLoops>
                                                                        </RelOp>
                                                                        <RelOp AvgRowSize="9" EstimateCPU="2.157E-06" EstimateIO="0" EstimateRebinds="0" EstimateRewinds="4095" EstimateRows="2" LogicalOp="Constant Scan" NodeId="31" Parallel="false" PhysicalOp="Constant Scan" EstimatedTotalSubtreeCost="0.00819216">
                                                                            <OutputList />
                                                                            <RunTimeInformation>
                                                                                <RunTimeCountersPerThread Thread="0" ActualRows="16384" ActualEndOfScans="8192" ActualExecutions="8192" />
                                                                            </RunTimeInformation>
                                                                            <ConstantScan />
                                                                        </RelOp>
                                                                    </NestedLoops>
                                                                </RelOp>
                                                                <RelOp AvgRowSize="9" EstimateCPU="2.157E-06" EstimateIO="0" EstimateRebinds="0" EstimateRewinds="4095" EstimateRows="2" LogicalOp="Constant Scan" NodeId="32" Parallel="false" PhysicalOp="Constant Scan" EstimatedTotalSubtreeCost="0.00819216">
                                                                    <OutputList />
                                                                    <RunTimeInformation>
                                                                        <RunTimeCountersPerThread Thread="0" ActualRows="32768" ActualEndOfScans="16384" ActualExecutions="16384" />
                                                                    </RunTimeInformation>
                                                                    <ConstantScan />
                                                                </RelOp>
                                                            </NestedLoops>
                                                        </RelOp>
                                                        <RelOp AvgRowSize="9" EstimateCPU="2.157E-06" EstimateIO="0" EstimateRebinds="0" EstimateRewinds="4095" EstimateRows="2" LogicalOp="Constant Scan" NodeId="33" Parallel="false" PhysicalOp="Constant Scan" EstimatedTotalSubtreeCost="0.00819216">
                                                            <OutputList />
                                                            <RunTimeInformation>
                                                                <RunTimeCountersPerThread Thread="0" ActualRows="65536" ActualEndOfScans="32768" ActualExecutions="32768" />
                                                            </RunTimeInformation>
                                                            <ConstantScan />
                                                        </RelOp>
                                                    </NestedLoops>
                                                </RelOp>
                                            </ComputeScalar>
                                        </RelOp>
                                    </Segment>
                                </RelOp>
                            </SequenceProject>
                        </RelOp>
                    </QueryPlan>
                </StmtSimple>
            </Statements>
        </Batch>
    </BatchSequence>
</ShowPlanXML>

由于许多交叉连接,第二个更大。

答案 2 :(得分:1)

将您的numbers_are_complete约束查询转移到INSERT/UPDATE/DELETE触发器中,您应该没有问题。