[转]SQL Server 2000执行计划成本(5/5)

Insert、Update和Delete

      SQLServer里3个写操作是INSERT、UPDATE和DELETE(IUD)。如果加上约束、触发器和外键,写操作可以变得更复杂。这里仅关心基本的写操作。对于3个操作中的每一个,对于堆表和有聚集索引的表来说都有不同的图标,如图2-31、2-32和2-33所示。


图2-31.堆表和有聚集索引的表的Insert执行计划



图2-32.堆表和有聚集索引的表的Update执行计划



图2-33.堆表和有聚集索引的表的Delete执行计划


      图2-34显示了表插入的成本计划,图2-35显示了聚集索引插入的成本细节。图2-36和图2-37显示了表更新和聚集索引更新的成本细节。图2-38和图2-39显示了表删除和聚集索引删除的成本细节。
      即使在表(堆)和聚集索引操作上的更新和删除操作有些不同,但成本几乎是一样的。索引搜索操作和在堆表里的表更新操作是分开的,但对聚集索引来说就是其中的一部分了。


图2-34.表插入成本细节



图2-35.聚集索引插入成本细节



图2-36.表更新成本细节



图2-37.聚集索引更新成本细节



图2-38.表删除成本细节



图2-39.聚集索引删除成本细节


      插入的I/O成本看来主要依靠表里目前的行数,如图C-1显示。插入的I/O成本对于每页320行和每页99行是相同的,而每页95行最高。然后I/O成本的差异少于0.7%。I/O成本相对于行的改变要在SQLServer停止重启后才能观察。这个改变在其他环境下是否能观察到还是个未知数。

图C-1.插入的I/O成本相对于目前表里的行的变化


      插入的I/O成本更少的依赖于每页的行数,表是否有聚集索引是一个非常微小的因素。图C-2显示了显示了与每页的行数的依赖关系。在表有无聚集索引之间的I/O成本的差异在第5个小数位。

图C-2.插入的I/O成本

 

      更新操作可能是更新或插入或删除操作,依赖于被修改的列是固定列还是可变长列和是否有足够的空间来存储新的可变长数据。
有时候需要插入几行到表里(不是来源于其他源)。通常的选择是分别写几个独立的Insert语句,这样每个语句会导致高的I/O成本(0.010021)。

INSERT N1C(ID,Value) VALUES (321,'TYI539087J'
INSERT NIC(ID,Value) VALUES (322,'TYI539087J')

一个可选的方法是使用union操作符把数据形成一个单个的行集,如下所示:

INSERT N1C(ID,Value) 
SELECT 321,'TYI539087J' 
UNION ALL 
SELECT 322,'TYI539087J' 

用UNION ALL子句的Insert语句的执行计划如下:


图2-40.使用UNION ALL操作符插入2行


在上面的例子里,常量扫描(Constant Scan)、串联(Concatenation)和Top操作符增加很小的成本(仅仅CPU),但插入的I/O成本只有一次。

Constant Scan CPU Cost = 0.000001157 per row 
Concatenation CPU Cost 
= 0.000000100 per row 
Top CPU Cost = 0.000000100 per row 

还有其他操作符如并行操作选项。如果时间允许的话再做讨论。


执行计划成本综述
      执行计划成本规则的以下几点值得注意:

  • 索引搜索成本不依赖于索引深度
  • 书签查找成本不依赖于表类型(堆表还是有聚集索引的表)
  • 索引搜索和书签查找的I/O成本依赖于平台,其他成本不是
  • 锁暗示(行锁、页锁、表锁)不影响成本规则
  • 在索引搜索和连接操作里增加行的每行成本通常比最初的行的成本低。

      这几点适合于SQLServer查询优化器用来决定最优的执行计划的成本规则。SQLServer文档没有地方宣称有所有影响查询成本的执行计划成本规则的因素。成本规则是否基于实际的测量或者代码路径长度估计的一些形式也是没有阐明的。
理想地,成本规则应该尽可能的准确以便查询优化器能做出最好的执行计划的决定。由于我们还不知道这些成本规则和实际的测量值是怎样比较的,所以此时还不能从真实的查询成本里得到更好的结论。
      此时可以做出一个结论。有时候需要用测试数据评估数据库应用程序,而不是用生产环境下的数据。为了为产品数据库观察可能的查询执行计划,仅需要用正确的分布数据来产生填充测试数据库。不必填充整个预期的产品环境的大小。例如,在一个订单数据库里,如果典型的客户在Orders表里有10条记录且每笔订单在Order_Line表里也有10条记录,那么用那种分布填充一些测试客户可以生成除书签查找和表扫描的预期的执行计划。

 

posted @ 2008-12-23 13:12  killkill  阅读(654)  评论(0编辑  收藏  举报