索引的物理设计决策涉及以下几类问题
该属性必须是一个码,或者必须存在某个查询,其选择条件或连接条件使用了该属性。之所以会建立多个索引。其因素之一有些查询只需扫描索引即可处理,而无需检索任何数据。
可以在一个或多个属性上建立索引。如果一个关系的多个属性共同出现在若干个查询中,则一般会使用多属性索引。多属性索引中的属性顺序可以考虑按照其区分度进行排序。
是否建立聚簇索引。一个表中最多只能有一个主索引或聚簇索引,因为该表必须按照这个属性物理排序。
在大多数关系数据库中,都用关键词CLUSTER来指定聚簇索引(如果是码属性便创建主索引,如果不是码属性则创建聚簇索引)。
如果一个表中需要多个索引,那么将哪个索引作为聚簇索引则取决于是否需要按照该属性排序。
聚簇索引最适合用于范围查询。
如果有多个属性需要范围查询,那么选择哪个索引作为聚簇索引则取决于是否要在该属性上对数据进行排序。
如果一次查询只进行一次索引排序(没有数据记录存取过程),则相应的索引不应该被聚簇,因为聚簇的最大优点体现在数据记录存取过程中。当由复合键检索的范围用于报表创建时,聚簇索引就可能建立为多属性索引。
关系数据库管理系统中使用B+树作为索引,某些系统也提供散列索引**。B+树索引支持作为搜索码的属性上的等值查询和范围查询。**
散列索引应用于等值查询,尤其是在连接操作中查找匹配记录时。
索引的使用要恰到好处,其使用原则一般如下
经常在查询中作为被使用的列,应为其建立索引
频繁进行排序或分组的列,应为其建立索引
一个列的值域很大时,应为其建立索引
如果待排序的列很多个,应为其建立索引
可以使用系统工具来检查索引的完整性,必要时进行修复。当数据库表更新大量数据后,删除并重建索引也可以提高查询速度。
在运行Order by 和group by的SQL语句时,会涉及排序的操作,**应当简化或避免对大型表进行重复的排序,因为磁盘的开销是很大的。**与内存排序相比较,磁盘排序操作很慢。从而会花费很长时间,降低数据库性能,而且磁盘排序会消耗临时表空间中的资源。当能够利用索引自动以适当的次序产生输出时,优化器就可以避免不必要的排序步骤。以下是一些影响因素: ①由于现有索引的不足,导致排序时索引中不包括一个或几个待排序的列。 ②group by或 order by子句中列的次序与索引的次序不一样。 ③排序的列来自不同的表。 为了避免不必要的排序,就要正确地增建索引,合理地合并数据库表(尽管有时可能影响表的规范化,但相对于效率的提高是值得的)。如果排序不可避免,那么应当试图简化它,如缩小排序列的范围等。
**在嵌套查询中,对表的顺序存取对查询效率可能产生致命的影响。避免这种情况的主要方法就是对连接的列进行索引。**还可以使用并集来避免顺序存取。尽管在所有的检查列上都有索引,但某些形式的where子句强迫优化器使用顺序存取.
在使用正则表达式进行条件查询时可能会消耗较多的CPU资源进行字符串匹配工作,因此应尽量避免。
把表的一个子集进行排序并创建临时表,有时能加速查询。它有助于避免多重排序操作,而且在其他方面还能简化优化器的工作。临时表中的行比主表中的行要少,而且顺序就是所要求的顺序,减少了磁盘的IO操作,所以查询工作量可以得到大幅减少。
非顺序磁盘存取是最慢的操作。但是在写SQL语句时往往忽略了这一点,使得在写应用程序时很容易写出要求存取大量非顺序页的查询,导致效率降低。有些时候,可以使用以数据库排序功能为基础的SQL来替代非顺序的存取,以改进查询效率。
尽量不要使用左右连接,左右连接消耗的资源多,包含了NULL数据匹配的数据。尽可能使用内连接。
平时每次向数据库发送的SQL脚本,都需要先编译后执行。对于相同的sql语句效率很低。存储过程不需要编译就可以直接执行,因此速度很快。
**频繁使用的sql语句建议使用存储过程。**另外:注意在存储过程中尽量使用SQL自带的返回参数,而非自定义的返回参数,减少不必要的参数,避免数据冗余。
游标会占用较多的资源,尤其在大规模并发情况下,很容易使得系统因资源耗尽而崩溃。 游标使用后应及时关闭和销毁,以释放资源。
多个处理放入事物中,系统的处理速度会有所下降,因此在保证数据库一致性的前提下,将频繁操作的多个可分割的处理过程放入到多个存储过程中,这样大大提高系统的响应速度。