现在已经知道了哪些查询模式需要进行优化,可以着手更具体的查询优化步骤了。这一步会设计到索引优化和查询代码优化。
SQL Server的数据库引擎顾问是一种工具。它可对输入的工作负荷进行分析,在此基础上为数据库优化提供建立。没有聚集索引的表被称为堆,拥有聚集索引的表叫聚集索引表(或聚集表)。
索引是一种用于排序和搜索的结构。在查找数据库时,索引可以减少对I/O的消耗。
页和区
页是SQL Server存储数据的基本单元,大小为8KB。它可以包含表,索引,分配位图,可用空间信息等。页是SQL Server可以读写的最小I/O单元。即使只需访问一行, SQL Server也要把整个页加载到缓存,再从缓存中读取数据。对于基本数据操作所涉及的查询,其开销主要是I/O开销。
区是由8个物理上连续的页组成的单元。当表或索引需要更多的空间存储数据时,SQL Server会为对象分配一个完整的区。对于包含少量数据的对象,有一个例外:如果对象不足64KB,则当需要更多的空间时,SQL Server通常分配一个单独的页,而不是整个区。
表的组织方式
表有两种组织方式:堆或B树。从技术上来说,当在表上创建一个聚集索引时,表就组织成一个B树;否则就组织成一个堆。所以表的组织方式也称为HOBT(Heap Or B Tree)。无论如何组织,表都可以定义0个或多个非聚集索引,而非聚集索引又会组织成B树。
堆(heap)是不含聚集索引的表。它被称之为堆是由于它存储的数据不按照任何顺序组织,而是按分区对数据进行组织。在一个堆中,用于保存数据之间关系的唯一结构是一个索引分区映射(IAM,Index Allocation Map)的位图页。
聚集索引
SQL Server中所有的索引都组织为B树结构,B树是平衡树的一种特例。平衡树的定义是“不存在叶子节点比其他叶子节点到根的距离要远的多的树”。它在叶子节点中维护整个表的所有数据。聚集索引不是数据的副本,而是数据本身。
当SQL Server需要对索引的页层执行无需扫描时,可以使用IAM页,这种扫描称为分配顺序扫描(allocation order scan)。而按照索引顺序完成的扫描称为索引顺序扫描(index order scan)。如果索引的碎片级别较高,则顺序扫描要慢得多。
当SQL Server需要导航到位于叶级的特定键时,它总是从根页开始,使用一种称为索引查找(index seek)的访问方法。这些读操作的I/O称为随机I/O,其读取次数和索引级别是一样多的。
堆上的非聚集索引
非聚集索引也结构化为一颗B树,而且在许多方面都和聚集索引类似。唯一的区别是非聚集索引的叶级行只包含索引键和特定的行定位符(row locator)。行定位符它是一个8字节的物理指针(RID),它由数据库中文件号,文件中的目标页号,目标页的行号组成。因此SQL Server必须在查找操作之后,执行一个RID的查找操作,对于大量的数据而言,开销会非常高。
聚集表上的非聚集索引
在聚集表上创建的非聚集索引和在堆上创建的非聚集索引,唯一的区别是:前者的行定位符是一个称为聚集键的值,而不是RID。其原理是指向逻辑的行,而不是物理的行。