设为首页 收藏本站
查看: 963|回复: 0

[经验分享] 《Microsoft Sql server 2008 Internals》读书笔记--第八章The Query Optimizer(9)

[复制链接]

尚未签到

发表于 2015-6-28 18:30:56 | 显示全部楼层 |阅读模式
  《Microsoft Sql server 2008 Internal》读书笔记--目录索引
  
  本文继续关注分区表(Partitioned Tables) 和数据仓库(Data Warehousing)
  SQL Server 2005针对分区表的并行查询的执行有一个局限性。APPLY操作符的使用在对扫描每个交互的分区时有限制,即允许SQL Server 2005对每个表只允许一个线程。虽然也允许并行查询。但大多数情况下还是被忽略了。而且,APPLY模式不考虑分区的大小差异,仍然使用一个线程处理一个最大或最小的分区。
  查询优化器在分区琢计划生成时改善了端对端体验。代表分区表的能力使访问分区表和非分区表的差异已经最小化。特别,可参考的并行计划集更加连贯。查询执行组件会动态调整每分区使用一个或多个线程,以便更高效地执行查询。
  在SQL Server 2008中,连接协作仍使用apply/nested loops join表示,但其他的案例使用传统表示。
http://public.blu.livefilestore.com/y1p-MQU_HZJLIWOEbfNHSkKwzRYGEZfz8pnMvIGMccbrSUfTKGcojjYwwLaZpd4p5RtHibK-mQaA9oIppFq251Uyw/2010-06-24%2023-38-15.png?psid=1
http://anp73g.blu.livefilestore.com/y1pzcJYbsg5Dyk38Qifxc8oFptLvGSwMBCggA1TpWa9sQcbPfX9BBUAP_3nPLFCnf44wLuu8me7vb8aV5PZ56mer9zrOR20XN0J/2010-06-24%2023-51-39.png?psid=1
  尽管SQL Server 2005在查询计划中暴露了分区ID,但SQL Server 2008在视图中极大隐藏了它。
  ■数据仓库(Data WareHouseing)
  SQL Server包括一些特定的优化以加速数据仓库的查询。数据仓库,其实就是一个大的事实数据和一些小的维度数据表和一些事实表引用的明细信息。即所谓的星型架构和雪花型架构。
  数据仓库通常尽力使事实表的每行尽可能小。大的数据,比如字符串,被移走到维度表以消减行内空间。当针对数据仓库作优化时,重要的是不到必要时不扫描事实表。SQL Server能辨识星型和雪花型架构。应用特殊的优化以改善查询性能。首先,SQL Server在数据仓库中排序不同的连接尽量使得扫描事实表前先执行一系列
  针对维度表的限定操作。 SQL Server 2008也包含针对(帮助减少并行查询时跨线程的数据移动的)位图操作的改进。位图可能会被消减会一个位(bit)。
  ■Updates
Updates在查询处理中是一个有趣的区域。不仅优化了传统的select查询,而且Updates优化也考虑物理优化比如在每行中多少索引需要被touch,进程是在一段时间内更新还是立即更新,尽可能快的处理变化而避免不必要的死锁等等。
  在这部分,我们将要讨论有关的优化。Update处理实际上包含了改变数据的顶级命令(top-level),Insert,Update,Delete,还有SQL Server 2008新增的Merge。SQL Server几乎一视同仁地对待这些命令。SQL Server中每个Update查询由如下的基本操作组成:
  1、决定什么行将被改变(Inserted,updated,deleted,merged)
  2、计算任何改变列的新值
  3、应用变化到表和任何非聚集索引的结构。
  下面的例子显示了Insert操作的查询计划:


Create table update1(col int primary key identity,col2 int ,col3 int)
gohttp://anp73g.blu.livefilestore.com/y1pwYM7RtAisr0rNlT8eU7cJ5jrrMO-FyNFV0uqZ1xGlgOTlZgov6Wb-9O2pL9EmxMmfJvDiyp2BytJDi_a_YKl0Fl5amQmr2hA/2010-06-29%2010-46-44.png?psid=1
  注意:Insert查询有一个运算符叫常量扫描(Constant Scan),一个常量扫描在关系代数学中是一个特殊的运算符,它不从表中读取数据而生成行。如果正在往表中插入新行,实际上表中并不存在该行。因此,这个运算符(Constant Scan)创建一个Insert操作来处理(在这个处理过程中,实际上新行并没有被插入)。计算标量操作计算这些值到Inserted中。在上例中,这是一个常量,但实际中可能是任何随意的标量表达式或标量子查询。最后,Insert操作物理地更新主键--聚集索引。
  下面的例子显示了Update操作的查询计划:
http://anp73g.blu.livefilestore.com/y1pPsf_6TYfpvKg7EMMTG_Jh5VfEeM19SxucSVH_PBpBFutSRmkAniYuq2KvwPuWVukf4GXgiwL0x-v_gIpZRZHMLw3vMEpWrTG/2010-06-29%2010-58-17.png?psid=1
  Update查询从聚集索引中读取值,执行一个Top操作,更新相同的聚集索引。这个Top操作实际上是一个处理ROWCOUNT的容器。除非在会话中执行一个set Rowcount  N操作,这个Top必须执行。同时注意本例中,更新命令并没有修改键值到聚集索引。因此,索引中的行并不需要在索引中移动。最后,似乎并没有一个操作符计算新值5到col2。这是错误的!事实上,它被处理了,只是有一个物理优化分解这个命令到Update中去处理了。如果你检查update属性,实际上,查询被直接自动参数化并且目标值被直接提供给了Update操作。
  下面的例子显示了Delete操作的查询计划:
http://anp73g.blu.livefilestore.com/y1pbQhTMr-syN61uRujWoLxZhNX9ZzoczUSAsQMdm9s7xbD_0NweegRr5et55mbWAG6qp4oRkQ-p7hn_R7qwcK2LCCRbEEM9N4m/2010-06-29%2011-19-15.png?psid=1
我们看到,Delete查询和Update查询非常类似,真实区别是:行最终被删除了。最原始的区别是一个where子句被作为一个条件应用到原始表的Seek操作。
需要注意的是:SQL Server对于物理表和索引生成不同的查询计划。我们看一个简单的例子:


Create table update2(col int,col2 int ,col3 int)
go
http://anp73g.blu.livefilestore.com/y1pB7SESmhYnKVziQCto40ys_vfIwKt2nvjjyo77aJPQon_wLtqV3P39JKtKKOrSfjQqvWzpKWvjDo27EaR_VEHantMIr72frhd/2010-06-29%2011-25-56.png?psid=1
  而当一个表是Heap(即没有聚集索引的表时),一个特殊的优化会把操作分解为更小的形式。这称为简单更新(Simple Update,这里的Update包括insert,update,delete,merge计划),它明显加快了速度。但注意仅对Heap有效。
我们看一个Heap例子:


Create table update3(col1 int,col2 int ,col3 int)
go
create index i1 on update3(col1);
create index i2 on update3(col2);
create index i3 on update3(col3);http://anp73g.blu.livefilestore.com/y1pn9F8Qne_MNaIVjqPX6Ay67_p0JXEDztLXfWFQ4v4yiRvQbHa6VnSoUOyZDJY_arhXan_aY90-K_LFy0fueZ1Y6ZdWhAKkLyH/2010-06-29%2011-48-05.png?psid=1
请注意这个查询更新了所有的索引。因为一个新行被创建了。然而,在上图中为什么只有一个操作呢?原来,实际的更新操作都在一个操作中了,如下图:
http://anp73g.blu.livefilestore.com/y1pmtNGaCreR1HHiXseujxkFvjRcs0fLTp2rYhn5cLo1Uv68K5muAwr4dnU0Mbqja9VnIuSo9923SXSOZQVJqNjZ6OpuBs_k9ZR/2010-06-29%2011-50-05.png?psid=1
  另外一个用于改善通用update场景的物理优化是:all-in-one或per-row操作。
  我们试着更新,但不更新所有的索引。


update update3 set col2=5 , col3=5http://anp73g.blu.livefilestore.com/y1pQYLW0wDE2lu9szaT0cos67t4BgAe9dkHLi4OwMlIZ158zTt9ym6lKcF7Sb3MNuQDzLbbf4-ZN00I_b_g1oUTrYrXRgo_VVUs/2010-06-29%2011-59-14.png?psid=1
  结果,查询变复杂了,查询在表扫描操作中扫描Heap,执行RowCOUNT top,两个计算标量,一个表更新。此时,查看Update的属性,可以看到只更新i2,i3索引。两个计算标量一个是计算新的值,另一个也是一个物理优化以帮助确认每行是否需要更新,每个索引是否需要更新。SQL Server内置一套机制,包含了处理非更新的Update。即如果表或索引没有变化,则某些列无需更新。
后面几篇将继续关注SQL Server的update计划机制。

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-81302-1-1.html 上篇帖子: 《Microsoft Sql server 2008 Internals》读书笔记--第九章Plan Caching and Recompilation(4) 下篇帖子: SQL Server 2008 R2 死锁监控
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表