日期:2014-05-18  浏览次数:20478 次

如何加快多条件查询速度
sqlserver2000 数据库如一个表table有id,a,b,c,d,e,f,g,h字段,id为自增id,a,b,c,d字段有字符型也可能有数字型
现在要根据a,b,c,d来查询,查询条件可能是:
1,只查询a,b,c,d每个字段的单独查询。如:
  select id,a,b,c,d,e,f,g,h from table where a='aaa'
  select id,a,b,c,d,e,f,g,h from table where b='bbb' 
  select id,a,b,c,d,e,f,g,h from table where c='ccc'
  select id,a,b,c,d,e,f,g,h from table where d='ddd' 
2,也可能组合a和b,或c和d来查询,如:
  select id,a,b,c,d,e,f,g,h from table where a='aaa' and b='bbb'
  select id,a,b,c,d,e,f,g,h from table where c='ccc' and d='ddd'

如何加快查询速度,有的说用组合索引,如a字段和b字段组合在一起,并且a字段放在前面,但单独查b字段时则慢了啊。
id是否建聚集索引,不建的话,如果查询单条数据是否会变慢,如:
  select id,a,b,c,d,e,f,g,h from table id=10

怎样建立合理的聚集索引和非聚集索引和组合索引呢?

 

------解决方案--------------------
SQL code

使用聚集索引和非聚集索引的区别
使用聚集索引 

    聚集索引确定表中数据的物理顺序。聚集索引类似于电话簿。由于聚集索引规定数据在表中的物理存储顺序,因此一个表只能包含一个聚集索引。但该索引可以包含多个列(组合索引),就像电话簿按姓氏和名字进行组织一样。

聚集索引对于那些经常要搜索范围值的列特别有效。使用聚集索引找到包含第一个值的行后,便可以确保包含后续索引值的行在物理相邻。避免每次查询该列时都进行排序,从而节省成本。 

注意事项 
定义聚集索引键时使用的列越少越好。 
1、包含大量非重复值的列。 
2、使用下列运算符返回一个范围值的查询:BETWEEN、>、>=、< 和 <=。 
3、被连续访问的列。 
4、返回大型结果集的查询。 
5、经常被使用联接或 GROUP BY 子句的查询访问的列;一般来说,这些是外键列。对 ORDER BY 或 GROUP BY 子句中指定的列进行索引,可以使 SQL Server 不必对数据进行排序,因为这些行已经排序。这样可以提高查询性能。 
6、OLTP 类型的应用程序,这些程序要求进行非常快速的单行查找(一般通过主键)。应在主键上创建聚集索引。 


聚集索引不适用于: 

1、频繁更改的列 。这将导致整行移动(因为 SQL Server 必须按物理顺序保留行中的数据值)。这一点要特别注意,因为在大数据量事务处理系统中数据是易失的。

2、宽键 。来自聚集索引的键值由所有非聚集索引作为查找键使用,因此存储在每个非聚集索引的叶条目内。

使用非聚集索引 

非聚集索引与课本中的目录类似。数据存储在一个地方,索引存储在另一个地方,索引带有指针指向数据的存储位置。索引中的项目按索引键值的顺序存储,而表中的信息按另一种顺序存储(这可以由聚集索引规定)。如果在表中未创建聚集索引,则无法保证这些行具有任何特定的顺序。 

多个非聚集索引 
有些书籍包含多个索引。例如,一本介绍园艺的书可能会包含一个植物通俗名称索引,和一个植物学名索引,因为这是读者查找信息的两种最常用的方法。对于非聚集索引也是如此。可以为在表中查找数据时常用的每个列创建一个非聚集索引。 


注意事项

在创建非聚集索引之前,应先了解您的数据是如何被访问的。可考虑将非聚集索引用于: 
? 包含大量非重复值的列,如姓氏和名字的组合(如果聚集索引用于其它列)。如果只有很少的非重复值,如只有 1 和 0,则大多数查询将不使用索引,因为此时表扫描通常更有效。 
? 不返回大型结果集的查询。 
? 返回精确匹配的查询的搜索条件(WHERE 子句)中经常使用的列。 
? 经常需要联接和分组的决策支持系统应用程序。应在联接和分组操作中使用的列上创建多个非聚集索引,在任何外键列上创建一个聚集索引。 
? 在特定的查询中覆盖一个表中的所有列。这将完全消除对表或聚集索引的访问。

索引都是一种排序,只是聚集索引的排序和物理表中的数据排序相同,一致的;而非聚集索引的排序和物理表数据的排序不同。

当我们在更新统计信息的时候,对于那些聚集索引列不但要更新索引页还要同时对数据物理表数据重新排序;而对非聚集索引列则只需要更新索引页

------解决方案--------------------
1.合理使用索引
索引是数据库中重要的数据结构,它的根本目的就是为了提高查询效率。现在大多数的数据库产品都采用IBM最先提出的ISAM索引结构。索引的使用要恰到好处,其使用原则如下: 
●在经常进行连接,但是没有指定为外键的列上建立索引,而不经常连接的字段则由优化器自动生成索引。 
●在频繁进行排序或分组(即进行group by或order by操作)的列上建立索引。 
●在条件表达式中经常用到的不同值较多的列上建立检索,在不同值少的列上不要建立索引。比如在雇员表的“性别”列上只有“男”与“女”两个不同值,因此就无必要建立索引。如果建立索引不但不会提高查询效率,反而会严重降低更新速度。 
●如果待排序的列有多个,可以在这些列上建立复合索引(compound index)。 
●使用系统工具。如Informix数据库有一个tbcheck工具,可以在可疑的索引上进行检查。在一些数据库服务器上,索引可能失效或者因为频繁操作而使得读取效率降低,如果一个使用索引的查询不明不白地慢下来,可以试着用tbcheck工具检查索引的完整性,必要时进行修复。另外,当数据库表更新大量数据后,删除并重建索引可以提高查询速度。 

(1)在下面两条select语句中:
select * from table1 where field1<=10000 and field1>=0;
select * from table1 where field1>=0 and field1<=10000;
如果数据表中的数据field1都>=0,则第一条select语句要比第二条select语句效率高的多,因为第二条select语句的第一个条件耗费了大量的系统资源。
第一个原则:在where子句中应把最具限制性的条件放在最前面。

(2)在下面的select语句中:
select * from tab where a=… and b=… and c=…;
若有索引index(a,b,c),则where子句中字段的顺序应和索引中字段顺序一致。
第二个原则:where子句中字段的顺序应和索引中字段顺序一致。

以下假设在field1上有唯一索引I1,在field2上有非唯一索引I2。
(3) select field3,field4 from tb where field1='sdf' 快
select * from tb where field1='sdf' 慢,
因为后者在索引扫描后要多一步ROWID表访问。

(4) select field3,field4 from tb where field1>='sdf' 快
select field3,field4 from tb where field1>'sdf' 慢
因为前者可以迅速定位索引。

(5) select field3,field4 from tb where field2 like 'R%' 快
select field3,field4 from tb where field2 like '%R' 慢,
因为后者不使用索引。

(6) 使用函数如:
select field3,field4 from tb where upper(field2)='RMN'不使用索引。
如果一个表有两万条记录,建议不使用函数