代码改变世界

查询优化(4)

2010-06-24 11:21  知行思新  阅读(1439)  评论(1编辑  收藏  举报

继续查询优化(3),还是讨论索引

注意列的顺序

只有在一个查询的条件与索引最左侧的键匹配时,这个索引才是有效的。举例来说,如果一个索引有一个组合键last_name, first_name,当查询的条件为where last_name = ‘Smith’ 或 where last_name = ‘Smith’ and first_name = ‘John’ 时,这个索引对此查询是有效的。但当查询的条件为where first_name = ‘John’ 时,这个索引就没有什么用了。

通常我们应该把选择性最高的列作为非聚集索引最左侧的键。举例来说,一个在emp_name, emp_sex上的索引比一个在emp_sex, emp_name更有用。对于PRIMARY KEY或UNIQUE约束而创建的组合键索引(索引键的顺序为定义约束列的顺序),我们要特别注意这一点。

在Join中使用的索引列

索引列经常被用来连接表。当我们创建一个PRIMARY KEY或UNIQUE约束时,SQL Server会自动创建一个索引。但SQL Server不会为FOREIGN KEY约束的引用列自动创建索引。FOREIGN KEY的引用列经常用来连接表,所以大多情况下我们应该为这些列创建索引。如果我们的PRIMARY KEY和FOREIGN KEY列冗长,我们可以考虑使用identity列来作为代理键(或使用类似方法)。如果我们能使索引键变得精简,一个数据页中就能存放更多的键,这意味着更少的I/O开销和更好的缓存效率。如果我们能通过像identity列的整数值来连接表,就能避免一个字符一个字符的比较。理想情况下,最好连接表的列为整型。

在前几篇中我们讨论过SQL Server统计信息。对于表连接,有一个连接密度的概念,表示一个表中的一行平均会对应另一个表中的行数。对于一个唯一索引的列,其具有最低的连接密度,即对于连接最具选择性。

在需要的时候Create或Drop索引

如果我们发现创建的索引从不会被使用,我们应该把这些索引去除。不被使用的索引不但不会帮助数据查询,还会降低数据修改的效率。通过查看执行计划可以判断一个索引是否在某个查询中被使用了。但对于一个大型系统,要分析索引的使用情况并不是很容易。我们可以借助于SQL Server 2005提供的Database Engine Tuning Advisor (DTA)工具,或借助于SQL Server 2005提供的动态管理视图和函数(sys.dm_db_index_usage_stats, sys.dm_db_missing_index_groups, sys.dm_db_missing_index_group_stats, sys.dm_db_missing_index_details, sys.dm_db_missing_index_columns)来了解系统的索引使用情况。

有些时候我们要在某些固定的时间点(如月末或季末),跑大量的SQL脚本来生成复杂报表或做财务结算。我们可以设计一种机制在做这些批量处理之前先创建索引,在整个批量过程完成后去掉这些索引。这样可以使批量处理从索引中得益,同时又不会增加日常的OLTP的开销。