Mysql

关注公众号 jb51net

关闭
首页 > 数据库 > Mysql > SQL Server索引设计

SQL Server索引设计基础知识详解使用

作者:Lion Long

为了使索引的使用效率更高,在创建索引时,必须考虑在哪些字段上创建索引和创建什么类型的索引。索引设计不合理或者缺少索引都会对数据库和应用程序的性能造成障碍。高效的索引对于获得良好的性能非常重要。设计索引时,应该考虑相应准则

一、前言

索引设计不佳和缺少索引是提高数据库和应用程序性能的主要障碍。 设计高效的索引对于获得良好的数据库和应用程序性能极为重要。 本索引设计指南包含关于索引体系结构的信息,以及有助于设计有效索引以满足应用程序需求的最佳做法。

二、索引设计背景知识

就像一本书,书本末尾有一个索引,可帮助快速查找书籍内的信息。 索引是按顺序排列的关键字列表,每个关键字旁边是一组页码,这些页码指向可在其中找到每个关键字的页面。

行存储索引也一样:它是按顺序排列的值列表,每个值都有指向这些值所在的数据页面的指针。 索引本身存储在页上,称为索引页。

索引是与表或视图关联的磁盘上或内存中结构,可以加快从表或视图中检索行的速度。 行存储索引包含由表或视图中的一列或多列生成的键。 对于行存储索引,这些键以树结构(B+ 树)存储,使数据库引擎可以快速高效地找到与键值关联的一行或多行。

行存储索引将逻辑组织的数据存储为包含行和列的表,物理上以行数据格式(称为 行存储1)存储,或以名为列 存储的列数据格式存储。

为数据库及其工作负荷选择正确的索引是一项需要在查询速度与更新所需开销之间取得平衡的复杂任务。 如果基于磁盘的行存储索引较窄,或者说索引关键字中只有很少的几列,则需要的磁盘空间和维护开销都较少。 而另一方面,宽索引可覆盖更多的查询。 您可能需要试验若干不同的设计,才能找到最有效的索引。 可以添加、修改和删除索引而不影响数据库架构或应用程序设计。 因此,应试验多个不同的索引而无需犹豫。

数据库引擎的查询优化器可在大多数情况下可靠地选择最高效的索引。 总体索引设计策略应为查询优化器提供可供选择的多个索引,并依赖查询优化器做出正确的决定。 这在多种情况下可减少分析时间并获得良好的性能。

不要总是将索引的使用等同于良好的性能,或者将良好的性能等同于索引的高效使用。 如果只要使用索引就能获得最佳性能,那查询优化器的工作就简单了。 但事实上,不正确的索引选择并不能获得最佳性能。 因此,查询优化器的任务是只在索引或索引组合能提高性能时才选择它,而在索引检索有碍性能时则避免使用它。

行存储是存储关系表数据的传统方法。 “行存储”是指基础数据存储格式为堆、B+ 树(聚集索引)或内存优化表的表。 “基于磁盘的行存储”排除了内存优化表。

2.1、索引设计策略包括的任务

三、常规索引设计

了解数据库、查询和数据列的特征可以帮助设计出最佳索引。

3.1、数据库注意事项

设计索引时,应考虑以下数据库准则:

3.2、查询注意事项

设计索引时,应考虑以下查询准则:

3.3、列注意事项

设计索引时,应考虑以下列准则:

3.4、索引的特征

在确定某一索引适合某一查询之后,可以选择最适合具体情况的索引类型。 索引包含以下特性:

也可以通过SQL Server的设置选项自定义索引的初始存储特征以优化其性能或维护。 而且,通过使用文件组或分区方案可以确定索引存储位置来优化性能。

3.5、索引排序顺序设计指南

定义索引时,请考虑索引键列的数据是按升序还是按降序存储。CREATE INDEX、CREATE TABLE 和 ALTER TABLE 语句的语法在索引和约束中的各列上支持关键字 ASC(升序)和 DESC(降序):

当引用表的查询包含用以指定索引中键列的不同方向的 ORDER BY 子句时,指定键值存储在该索引中的顺序很有用。 在这些情况下,索引就无需在查询计划中使用 SORT 运算符。因此,使得查询更有效。

检索数据以满足此条件需要将 Purchasing.PurchaseOrderDetail 表中的 RejectedQty 列按降序(由大到小)排序,并且将 ProductID 列按升序(由小到大)排序,比如:

SELECT RejectedQty, ((RejectedQty/OrderQty)*100) AS RejectionRate,  
    ProductID, DueDate  
FROM Purchasing.PurchaseOrderDetail  
ORDER BY RejectedQty DESC, ProductID ASC;
GO

此查询的下列执行计划显示了查询优化器使用 SORT 运算符按 ORDER BY 子句指定的顺序返回结果集。

如果使用与查询的 ORDER BY 子句中的键列匹配的键列创建基于磁盘的行存储索引,则无需在查询计划中使用 SORT 运算符,从而使查询计划更有效。

CREATE NONCLUSTERED INDEX IX_PurchaseOrderDetail_RejectedQty  
ON Purchasing.PurchaseOrderDetail  
    (RejectedQty DESC, ProductID ASC, DueDate, OrderQty);
GO

再次执行查询后,下列执行计划显示未使用 SORT 运算符,而使用了新创建的非聚集索引。

总结

覆盖索引是针对非聚集索引的指定,它直接解析一个或几个类似的查询结果,而不访问其基表,并且不会引发查找。 这意味着,由 SELECT 子句以及所有 WHERE 和 JOIN 参数返回的列都被索引所覆盖。 当与表本身的行和列相比,如果索引足够窄,那么执行查询的 I/O 可能会少得多,这意味着它是总列的一个真正子集。 如果选择大型表的一小部分,请考虑覆盖索引,其中的小部分是由一个固定谓词定义,比如一个稀疏列,例如它只包含几个非 NULL 值。

到此这篇关于SQL Server索引设计基础知识详解使用的文章就介绍到这了,更多相关SQL Server索引设计内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文