1、逻辑数据库和表设计数据库的逻辑设计,包括表之间的关系,是优化关系型数据库性能的核心。良好的逻辑数据库设计可以为优化数据库和应用程序打下良好的基础。标准化的数据库逻辑设计涉及用许多具有相互关系的窄表替换具有许多列的长数据表。以下是使用规范化表格的一些好处。A:因为表格比较窄,可以使排序和索引速度更快。B:由于有多个表,所以有可能存在多个索引。C:更窄更紧凑的索引。D:每个表中的索引可以少一些,这样可以提高insert、update、delete等操作的速度,因为当索引很多的时候,这些操作会对系统性能产生很大的影响。E:更少的空值和更少的冗余值增加了数据库的紧凑性。由于标准化,在获取数据时会增加引用表的数量和它们之间的连接关系的复杂性。太多的表和复杂的连接关系会降低服务器的性能,所以两者之间需要综合考虑。定义具有相关关系的主键和外键时主要要注意的是:用于连接多个表的主键和引用键必须具有相同的数据类型。二、索引的设计A:尽量避免表扫描检查你的查询语句的where子句,因为这是优化器的一个重要关注点。where中包含的每一列(column)都是一个可能的候选索引。为了获得最佳性能,请考虑下面给出的示例:对于where子句中给出的列column1。以下两种情况可以提高索引的优化查询性能!第一:表中column1上有一个索引;第二:表中有多个索引,但column1是第一个索引的列。避免定义多个索引,其中column1是第二个或后面的索引,这样的索引不能优化服务器性能。示例:以下示例使用pubs数据库。SELECTau_id,au_lname,au_fnameFROMauthorsWHEREau_lname='White'建立在以下列上的索引将是优化器有用的索引。发挥好au_addressau_fname,au_lname考虑在一列或两列上使用窄索引,窄索引比多索引和复合索引更有效。使用窄索引,每页将有更多的行和更少的索引级别(与多个和复合索引相比),这将提高系统性能。对于多列索引,SQLServer在索引的所有列上维护一个密度统计信息(用于连接),在第一个索引上维护一个直方图(histogram)统计信息。根据统计结果,如果复合索引上的第一个索引很少被使用,优化器将不会对很多查询请求使用该索引。有用的索引将提高select语句的性能,包括insert、uodate、delete。但是,通过更改表的内容,索引将受到影响。每个插入、更新、删除语句都会稍微降低性能。实验表明,不要在单个表上使用大量索引,也不要在共享列上使用重叠索引(指在多个表中使用的引用约束)。检查列上唯一数据的数量,并将其与表中数据的行数进行比较。这就是数据的选择性,对比结果会帮助你决定是否将某个列作为候选索引列,如果需要的话,建立哪个索引。您可以使用以下查询返回列的不同值的数量。selectcount(distinctcloumn_name)fromtable_name假设column_name是一个有10000行的表,看column_name的返回值来决定是否使用它,使用什么索引。UniquevaluesIndex5000Nonclusteredindex20Clusteredindex3Noindexarrowheadindex和nonclusterindex的选择<1>arrowheadindex就是行的物理顺序和索引的顺序一致。page-level、low-level等索引的每一层都包含实际的数据页。一张表只能有一个索引。由于更新和删除语句需要相对较多的读取操作,索引通常可以加快此类操作。您应该在至少有一个索引的表上有一个索引。以下几种情况,可以考虑使用索引:例如:某列不同值的个数是有限的(但不是极少)customer表的statename列有50个左右不同的statenames的缩写值,可以使用箭头进行索引。例如:箭头索引可以用于返回一定范围内的值的列,例如对具有between、>、>=、<、<=等的列进行操作的列。select*fromsaleswhereord_datebetween'5/1/93'and'6/1/93'例如:对于查询时返回大量结果的列,可以使用箭头索引。SELECT*FROMphonebookWHERElast_name='Smith'当向表中插入大量行时,避免在该表的自然增长(例如标识列)列上建立索引。如果创建索引,那么insert的性能会大大降低。因为每个插入的行都必须到表的末尾,即表的最后一个数据页。当一个数据正在插入时(此时数据页被锁定),所有其他插入的行必须等到当前插入结束。索引的叶级页包括实际的数据页,数据页在硬盘上的顺序与索引的逻辑顺序相同。<2>非箭头索引是行的物理顺序与索引的顺序不同。非标头索引的叶级包含指向行数据页的指针。一张表中可以有多个非表头索引,以下几种情况可以考虑使用非表头索引。在具有许多不同值的列上,您可以考虑使用非标题索引。例如:part表中的part_id列select*fromemployeewhereemp_id='pcm9809f'在查询语句中,可以考虑在该列上使用带orderby子句的无头索引。3、查询语句的设计SQLServer优化器通过分析查询语句自动优化查询,确定最有效的执行计划。优化器分析查询语句以确定哪些子句可以优化,并为可以优化的子句选择有用的索引。最后,优化器比较所有可能的执行计划并选择最有效的一个。执行查询时,使用where子句来限制必须处理的行数。除非绝对必要,否则应避免无限制地读取和处理表??中的所有行。例如下面的例子,selectqtyfromsaleswherestor_id=7131比下面的unlimitedqueryselectqtyfromsales更高效,以避免为客户的最终数据选择返回一个大的结果集。允许SQLServer运行功能以限制结果集的大小会更有效。当多个用户与并发关联时,这会减少网络I/O并提高应用程序性能。因为优化器的重点是查询where子句以利用有用的索引。表中的每个索引都可能包含在where子句中。为了获得最佳性能,请遵循给定列column1的以下索引。第一:表中column1上有一个索引;第二:表中有多个索引,但column1是第一个索引的列。不要在where子句中使用没有column1列索引的查询语句,避免在where子句中使用多索引首索引以外的索引。这时候,多个索引就没有用了。例如,给定pubs数据库中authors表的au_lname、au_fname列的多列索引,以下查询语句使用au_lname上的索引SELECTau_id,au_lname,au_fnameFROMauthorsWHEREau_lname='White'ANDau_fname='Johnson'SELECTau_id,au_lname,au_fnameFROMauthorsWHEREau_lname='White'下面的查询没有使用索引,因为他使用的是多索引索引,不是第一个索引SELECTau_id,au_lname,au_fnameFROMauthorsWHEREau_fname='Johnson'【编辑推荐】使用SQLServer2008的FILESTREAM特性管理文件是SQLServer中删除所有数据最简单的方法SQLServer2005中XML操作函数详解
