其他索引设计准则
设计索引时还要考虑的其它准则包括:
一个表如果建有大量索引会影响 INSERT、UPDATE 和 DELETE 语句的性能,因为在表中的数据更改时,所有索引都须进行适当的调整。另一方面,对于不需要修改数据的查询(SELECT 语句),大量索引有助于提高性能,因为 SQL Server 有更多的索引可供选择,以便确定以最快速度访问数据的最佳方法。
覆盖的查询可以提高性能。覆盖的查询是指查询中所有指定的列都包含在同一个索引中。例如,如果在一个表的 a、b 和 c 列上创建了组合索引,则从该表中检索 a 和 b 列的查询被视为覆盖的查询。创建覆盖一个查询的索引可以提高性能,因为该查询的所有数据都包含在索引自身当中;检索数据时只需引用表的索引页,不必引用数据页,因而减少了 I/O 总量。尽管给索引添加列以覆盖查询可以提高性能,但在索引中额外维护更多的列会产生更新和存储成本。
对小型表进行索引可能不会产生优化效果,因为 SQL Server 在遍历索引以搜索数据时,花费的时间可能会比简单的表扫描还长。
应使用 SQL 事件探查器和索引优化向导帮助分析查询,确定要创建的索引。为数据库及其工作负荷选择正确的索引是非常复杂的,需要在查询速度和更新成本之间取得平衡。窄索引(搜索关键字中只有很少的列的索引)需要的磁盘空间和维护开销都更少。而另一方面,宽索引可以覆盖更多的查询。确定正确的索引集没有简便的规则。经验丰富的数据库管理员常常能够设计出很好的索引集,但是,即使对于不特别复杂的数据库和工作负荷来说,这项任务也十分复杂、费时和易于出错。可以使用索引优化向导使这项任务自动化。有关更多信息,请参见索引优化向导。
可以在视图上指定索引。有关更多信息,请参见设计索引视图。
可以在计算列上指定索引。有关更多信息,请参见在计算列上创建索引。
索引的特征
在确定某一索引适合某一查询之后,可以自定义最适合具体情况的索引类型。索引特征包括:
聚集还是非聚集
唯一还是不唯一
单列还是多列
索引中的列顺序为升序还是降序
覆盖还是非覆盖
还可以自定义索引的初始存储特征,通过设置填充因子优化其维护,并使用文件和文件组自定义其位置以优化性能。
用 ORDER BY 对行进行排序
ORDER BY 子句按查询结果中的一列或多列对查询结果进行排序,用作排序依据的列总长度可达 8,060。有关 ORDER BY 子句最大大小的更多信息,请参见 SELECT。
排序可以是升序的 (ASC),也可以是降序的 (DESC)。如果没有指定升序还是降序,就假定为 ASC。
重要 ORDER BY 子句的确切结果取决于安装过程中所选的排序规则。有关不同排序规则所产生的影响的更多信息,请参见 SQL Server 排序规则基础知识。
下列查询返回按 pub_id 升序排列的结果。
USE pubs
SELECT pub_id, type, title_id
FROM titles
ORDER BY pub_id
下面是结果集:
pub_id type title_id
------ ------------ --------
0736 business BU2075
0736 psychology PS2091
0736 psychology PS2106
0736 psychology PS3333
0736 psychology PS7777
0877 mod_cook MC2222
0877 mod_cook MC3021
0877 UNDECIDED MC3026
0877 psychology PS1372
0877 trad_cook TC3218
0877 trad_cook TC4203
0877 trad_cook TC7777
1389 business BU1032
1389 business BU1111
1389 business BU7832
1389 popular_comp PC1035
1389 popular_comp PC8888
1389 popular_comp PC9999
(18 row(s) affected)
如果在 ORDER BY 子句中指定了不止一列,排序就是嵌套的。下列语句对 titles 表中的行进行排序,首先按出版商降序排列,然后在各出版商范围内按类型升序排列,最后按价格排序(同样是升序,因为未指定 DESC)。
USE pubs
SELECT pub_id, type, title_id, price
FROM titles
ORDER BY pub_id DESC, type, price
说明 不能对数据类型为 text 或 image 的列使用 ORDER BY。同样,在 ORDER BY 列表中也不允许使用子查询、聚合和常量表达式;不过,可以在聚合或表达式的选择列表中使用用户指定的名称,例如:
SELECT type, sum (ytd_sales) AS sales_total
FROM titles
GROUP BY type
ORDER BY sales_total