当前位置: 首页 > news >正文

server 容易让人误解的问题之 聚集表的物理顺序问题

对于MS SQL server 数据库,有几个容易让人产生误解的问题,对于这几个问题,即使很多 SQL server DBA 都有错误认识或者认识不充分,所以我想撰文几篇,把这些容易理解错误的问题前前后后深入阐述一下,也希望纠正一下网上对这几个问题的讹传(我也可能有认识不对的地方,欢迎批评指正)。

第一个问题:聚集表的物理顺序问题。这个问题很有迷惑性,因为很多教科书在讲到聚集索引的时候都会出现“聚集索引是按照聚集键的排序顺序物理地存储数据” 类似的说法,因此我们很容易产生以下几种误解:

误解一:“按顺序物理地存储”就是磁盘本身;

误解二:聚集表的页在物理上是顺序的;

误解三:聚集表的页在物理上是顺序的,并且是连续的。

下面我们分别说明上面三种观点确实是误解。

对于误解一,我们必须要了解数据行如何被存储在数据页上。

上图是我从MSDN上截来的,从上图可以看到,在每个数据页的末尾,都有一个“行偏移量”的数组,这个数组记录了每一个数据行的开头在页面中的起始位置,即每行数据开头应该从页头偏移多少个字节。我将上图改了一下,可能更便于正确理解:

我改编的这个图中表示,从这个数据页头偏移96个字节即是第一行数据的开始位置,偏移200字节即是第二行数据的开始位置,偏移300个字节即是第三行数据的开始位置。

下面我们举个实际的例子来说明聚集表的数据在一个数据页上可能的样子。

CREATE TABLE test ( RowId int not null primary key , Column1 char(100) ) INSERT INTO test(RowId,Column1) Select 1, ' ' Union Select 2,' ' Union Select 10,' '

对于上表,数据第一次插入时,这三行数据在数据页上的表现如下:

而如若我再往里面插入如下数据:

INSERT INTO test(RowId,Column1) Select 7, ' '

因为这个表的RowId 列有聚集索引(primary key 默认创建聚集索引),而数字7大约2,且小于10,那么SQL server 在执行INSERT 操作时,是不是会把RowId = 10 这行数据往下挪呢?显然SQL server 不会这么笨,而只会将RowId = 7这行数据数据附加到RowId = 10 这行数据的后面,然后再修改行偏移量数组,示意图如下:

现在我们应该可以明白:一个聚集索引表数据页上数据行的物理顺序,仅依靠行偏移列表来决定,并不取决于在磁盘上的物理位置。

对于误解二和误解三可以放在一起论述,在论述之前,我们需要先了解一下SQL server 存储引擎中页跟区的概念。
1. SQL server 中数据存储的基本单位是页。
2. 区是八个逻辑上连续的页的集合,用来有效的管理页,这也说明,所有的数据页一定属于某个区。
3. 区分为混合区和统一区。混合区中的页可以被分配给多个数据库对象;统一区中的页一定是被分配给了某一个数据库对象。
4. SQL server 在为某个数据库对象申请空间时,需要使用GAM,SGAM,PFS 系统页的信息,同时在空间被分配后,也会维护好GAM,SGAM,PFS系统页的息 。

上面我简单列出了几个要点,更多详细信息大家可以参考下面的链接信息:
http://msdn.microsoft.com/zh-cn/library/cc280360(v=sql.100).aspx

然后我将列举具体的情况来证明二跟三确实是误解:
1. 当我们新建一个聚集表,并且往表里插数据,当这个表所占用空间不够8个数据页时,SQL server存储引擎都将从混合区寻找空闲的页面分配给表。而在这个阶段内,很容易出现一个混合区被同时分配给多个数据库对象(最多可达8个数据库对象)。那么,如果我们的聚集表需要再次申请磁盘空间,就很可能在起初的混合区内分配到不连续的页(相对于已分配给这个聚集表的页来说),或者要从另外一个混合区查找空闲页面,这样,是无论如何也保证不了“聚集表的页在物理上是顺序的”,更保证不了“页是连续的”。

2. 如果一个聚集表满8个页,那么,后续所有的空间申请都将分配完整的统一区,这后续的统一区是否可以顺序,或者连续呢? 当然不行,当一个申请空间的动作发出后,存储引擎都会从表所在数据文件的第一个GAM去遍历查找空闲的统一区,如果某个统一区在之前已经分配给某个其它的数据库对象,但当前这个区已经被释放,那么,SQL server 就会将这个空闲的区分配给我们的聚集表,这样也自然保证不了页在物理上的“顺序和连续”;另外,即使SQL server每次都分配从来没有分配给任何数据库对象的区给我们的聚集表,也没有办法保证页在物理上的“顺序和连续”。

3. 如果聚集表出现分页的情况,那么新申请页的页面链的“上一页”会指向被分割的数据页,“下一页”会指向被分割页在分割前指向的下一页。显然,这种情况也没有办法保证页在物理上的“顺序和连续”,而且它是索引碎片情况中的一种。

http://www.jsqmd.com/news/1117815/

相关文章:

  • 洛雪音乐音源完全指南:解锁全网无损音乐的终极配置方案
  • NVIDIA RTX Spark:软硬一体重塑AI PC,开启本地大模型与智能体开发新范式
  • FactoryBluePrints深度解析:戴森球计划工厂效率革命实战指南
  • 2024自动驾驶五大现实断层:合规、感知、体验、成本与数据
  • 解放你的音乐!QMCFLAC2MP3:一键解密QQ音乐加密格式的终极方案
  • 生成式AI能力导航图:按任务选模型的实操决策指南
  • MuleSoft+LLM企业级AI编排实战:打通数据、流程与治理断层
  • Windows Server AD域集成CA部署:构建企业级PKI与自动化证书管理
  • 紧急预警:2024年Q2起OpenAI/Anthropic API新规将淘汰83%的野路子AI项目——立即升级你的本地化部署方案
  • 企业网盘文件同步核心技术解析:冲突检测、断点续传与增量同步
  • TikTok自动化神器:Python驱动的高效社交互动工具终极指南
  • Robot Framework自动化测试框架:从环境搭建到CI/CD集成的实战指南
  • 从黑客到猎人:漏洞赏金实战指南与年入百万方法论
  • Java21虚拟线程完全实战:彻底颠覆传统并发,万字高吞吐落地指南
  • 非全mba毕业论文选题
  • GLM-5.2 与 PowerMem 碰撞:七轮长程任务评测,展现稳定工程判断能力但仍留缺口
  • IS31FL3731 LED驱动与TM4C129微控制器实战指南
  • WinForm依赖注入实战:从原理到应用
  • 3分钟掌握百度网盘高速下载:Python解析工具实战指南
  • ICM-42688-P与STM32F745ZG在工业自动化中的高精度运动控制应用
  • PingFangSC字体终极指南:6种字重+双格式支持,如何为你的Web应用节省50%字体加载时间
  • 金融系统Java安全实战:纵深防御、安全左移与核心漏洞防护
  • 零代码SQLite数据库管理:DB Browser for SQLite完整指南
  • LV3296与PIC18F4620构建高效条码识别系统
  • 【Bug已解决】MCP error -32000: Connection closed 解决方案
  • 3大核心功能打造专业级Windows音频调校方案
  • 从入门到精通:openeuler/compiler-test中的测试套管理与维护终极指南
  • 微信聊天记录删了?3 种手机本地方法一键找回
  • 【独家首发】头部金融科技公司内部AI编程规范白皮书(含17条防Bug硬约束规则与自动化校验脚本)
  • WarcraftHelper:魔兽争霸III终极增强插件完整使用教程