在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表中的缺失值,但是如何约束表以便丢失值是不可能的?
答案 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
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
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
触发器中,您应该没有问题。