填充因子

T-SQL查询高级—SQL Server索引中的碎片和填充因子

谁说胖子不能爱 提交于 2019-11-27 11:20:17
写在前面:本篇文章需要你对 索引 和SQL中数据的 存储方式 有一定了解.标题中高级两个字仅仅是因为本篇文章需要我的T-SQL进阶系列文章的一些内容作为基础. 简介 在SQL Server中,存储数据的最小单位是页,每一页所能容纳的数据为8060字节.而页的组织方式是通过B树结构(表上没有聚集索引则为堆结构,不在本文讨论之列)如下图: 在聚集索引B树中,只有叶子节点实际存储数据,而其他根节点和中间节点仅仅用于存放查找叶子节点的数据. 每一个叶子节点为一页,每页是不可分割的. 而SQL Server向每个页内存储数据的最小单位是表的行(Row).当叶子节点中新插入的行或更新的行使得叶子节点无法容纳当前更新或者插入的行时,分页就产生了.在分页的过程中,就会产生碎片. 理解外部碎片 首先,理解外部碎片的这个“外”是相对页面来说的。外部碎片指的是由于分页而产生的碎片.比如,我想在现有的聚集索引中插入一行,这行正好导致现有的页空间无法满足容纳新的行。从而导致了分页: 因为在SQL SERVER中,新的页是随着数据的增长不断产生的,而聚集索引要求行之间连续,所以很多情况下分页后和原来的页在磁盘上并不连续. 这就是所谓的外部碎片. 由于分页会导致数据在页之间的移动,所以如果插入更新等操作经常需要导致分页,则会大大提升IO消耗,造成性能下降. 而对于查找来说,在有特定搜索条件

SQL 索引

☆樱花仙子☆ 提交于 2019-11-26 21:50:40
  初学C#的时候,用控制台实现过学生信息管理系统。那个时候所有的数据都是保存在泛型集合中,然后创建各种工厂类,各种继承多态……虽然最后做出来后感觉挺不错,但是数据的冗余大的不得了。在编码的时候还得写一个模块测试一个模块,一旦其中一个模块出现一点小小的BUG那么就会造成数据的不准确。   后来学到了数据库,发现用SELECT [字段1,字段2,……] from 表名 就能查到我需要的所有的数据。感觉挺不错,查询效率又高,有简便。不需要自己手动建什么工厂类啊,继承多态了。用的久了,会开始想探索下数据库的查询是怎么实现的。个人感觉,如果在一个表中执行查询,那么数据库会遍历所有行查找到符合条件的行,然后返回出来。实现思路和用C#实现学生信息管理系统差不多。这个时候就出现了这样一个问题,如果这个表里面的数据有上亿条,甚至是几亿亿条呢?难道说为了查找那么一行记录还要遍历所有行去找到符合条件的行?这样未免太浪费资源了吧!现在才知道,原来数据库还有一个叫索引的东西,就像是字典中的目录。比如说你要查找一个“城”字,只需要在目录中找到拼音ch的所在页区间,然后翻到指定的页区间中找,很快就能找到“城”字。因为有了索引,所以数据库的查找效率不会因为数据量的庞大而造成大幅度下降(当然是会下降一点点)。如果没有索引这个东西,就好比字典没有了目录,那么这个查找数据的效率就可想而知了。