zoukankan      html  css  js  c++  java
  • 查询优化器内核剖析第八篇:执行引擎之数据访问操作Seek(上)

    查询优化器内核剖析第八篇:执行引擎之数据访问操作---Seek(上)

    系列文章索引:       

    查询优化器内核剖析第一篇

    查询优化器内核剖析第二篇:产生候选执行计划&执行计划成本估算

    查询优化器内核剖析第三篇:查询的执行与计划的缓存 & Hint提示

    查询优化器内核剖析第四篇:从一个实例看执行计划

    查询优化器内核剖析第五篇:进一步的了解执行计划

    查询优化器内核剖析第六篇:谈谈Join的顺序问题,纠正江湖偏方

    查询优化器内核剖析第七篇:执行引擎之数据访问操作---Scan

    查询优化器内核剖析第八篇:执行引擎之数据访问操作---Seek与Lookup

    查询优化器内核剖析第九篇:执行引擎之数据访问操作---Bookmark Lookup

    查询优化器内核剖析第十篇:执行引擎之数据访问操作- Aggregations(聚合)

     

            前言:自从本系列文章开始以后,收到了一些朋友的来信,也有很多的朋友对我说,写内核分析的文章不受欢迎,因为没有多少人会关注这个东西。确实,每每在分析一些底层机制或者内核的时候,不断是书还是博客,很少能够特别“火”的。从自己的经验看来,作为一个技术人员,如果想要走得更远,更高,这些东西是很有必要的!也许大家还记得当我们遇到问题时候,无法下手的囧况,也许还记得,当我们做了一个修改之后,只能给出“可能会搞定”这样不确定的答案。为什么?因为东西掌握的不够深入,全面,导致我们顾此失彼,以至于心虚!

            曾经有朋友说:你是搞开发的,需要懂把数据库搞的那么深吗?我曾经也认为:确实没有必要,不是有DBA吗?后来,我发现我错了:第一,没有几个公司有很明确的DBA,很多时候开发人员做着DBA的事情;第二,数据库是一个应用的关键,性能优化,很大的程度上,都需要关注数据库;第三,如果想以后为项目做架构,做设计,不懂数据库,不考虑它的存储架构,设计,维护,性能,甚至是灾难恢复,如何敢说自己会做架构,如何扛起这么大一个责任。朋友们可能就说了:这么多,搞的完吗?看需要,需要啥,就去学习啥,开始的时候,为了应急,可以懂个大概,等时间有了,再深入!

            不得不承认我们技术界有些浮躁的气氛,存在着很多的“潜规则论“,”关系论“,”忽悠论“等,但是不管怎么样,作为一个技术人员,要过活下去,要有点竞争力,技术这一关是要扎扎实实过的!我们分析内核,不是单从理论上讲述,而是从实用的角度,我也不想浪费大家的时间去看毫无用处的文章,也不想浪费自己的时间写没有营养的东西。

    如果大家认为说的还有点道理,就接着往下看技术的部分;如果不赞同,大家可以选择不看下面的文章,避免浪费大家的 时间!

     

            在上一篇文章中介绍了Scan的操作,因为我每次都只是介绍一小点,所以,朋友们可能阅读起来没有感觉,一是因为这些东西确实不好讲,二是,我希望每次写一点,利于大家消化,等到整个系列文章完整之后,大家就会全面掌握这些知识的每一个细节,自己在啃这些东西的时候,也是一点点的消化的。

    说了这么多,我们言归正传,对于Seek,这个操作主要是发生在聚集索引和非聚集索引上面。

    为了讲明这个问题,我们依然采用的是数据库AdventureWorks,看看下面的一个例子,看到下面的查询:

     20120331111504.png

    我们运行这个查询并且查看它的执行计划,如下图:

     

    20120331111539.png

     

    很显然,这个查询最后在执行的时候,采用了Seek操作。

    下面,我们就来具体的看看,为什么?

    首先,我们讲解一下与数据库索引存储相关的知识。

     

            我们知道,聚集索引是按 B 树结构进行组织的,既然是B树组织,那么就有叶子结点和非叶子节点之分。聚集索引B 树的顶端节点称为根节点;聚集索引中的底层节点称为叶节点。在根节点与叶节点之间的任何索引级别统称为中间级。

            在聚集索引中,叶节点包含基础表的数据页。根节点和中间级节点包含存有索引行的索引页。每个索引行包含一个键值和一个指针,该指针指向 B 树上的某一中间级页或叶级索引中的某个数据行。每级索引中的页都处于链接在双向链接所在列表中。 

    可以这么说,聚集索引的叶子结点存储的是按聚集索引顺序排列的数据本身,而中间结点和根节点则在维护索引和其层级。如图:

     

    20120331111751.png

            对于每个聚集索引,在系统表 sys.system_internals_allocation_units 中的 root_page 列指向该聚集索引某个特定分区的顶部。下图就是sys.system_internals_allocation_units的数据:

     20120331111830.png

    SQL Server 将从索引中向下移动以查找与某个聚集索引键对应的行。

    为了查找键的范围,SQL Server 将在索引中移动以查找该范围的起始键值,然后用向前或向后指针在数据页中进行扫描。

    为了查找数据页链的首页,SQL Server 将从索引的根节点沿最左边的指针进行扫描。

    看完了上面的介绍之后,大家基本对聚集索引的存储有了大致的理解。

    下面我们首先来看看Person.Address表的聚集索引的定义: 

     

    20120331111937.png

                   大家看到上面的这个图,这个表的聚集索引就是AddressID。当查询在执行的时候,就会使用AddressID作为索引键通过B树一下子就找到了这个键对应的数据页,然后读数据!

  • 相关阅读:
    Sikuli:创新的图形化编程技术
    缺少对象 WScript 问题解决方法
    TD8.0迁移到QC9.2,自动迁移失败,手动迁移
    QTP使用小技巧
    外部VBS的调用
    mysql 发生系统错误1067的解决方法
    Mysql 本地计算机无法启动 mysql 服务 错误 1067:进程意外终
    windows下mysql忘记root密码的解决方法
    mysql 常用命令用法总结积木学院整理版
    java、c/c++ 、python 等性能比较 杂谈(整理)
  • 原文地址:https://www.cnblogs.com/yanyangtian/p/2426718.html
Copyright © 2011-2022 走看看