2007年9月
辽宁省交通高等专科学校学报
JOURNAL OF LIAONING PROVINCIAL COLLEGE OF COMMUNICATIONS
Vol.9No.3Sep.2007
文章编号:1008-3812(2007)03-041-02
SQLserver查询优化分析
李 娜
(黑龙江农垦管理干部学院信息中心,黑龙江哈尔滨 150090)
摘 要 随着应用系统中数据量的增大,提高数据库管理系统SQLserver的查询和访问数据功能极为必要。
本文就提高SQLserver的查询优化问题进行一些分析。
关键词 索引视图异步查询
中图分类号:TP311 文献标识码:A
1 引言
在应用系统中,对数据查询及处理速度已成为衡量应用系统成败的标准。数据库管理系统SQLSERVER由于其强大的信息操作和数据管理能力为大众所喜爱,随着它数据量的增大,如何提高查询的速度和效率是每一位软件人员不断探索的问题。数据库被建立以后,如何根据用户的需求快速得到数据库中的信息,这是数据库查询中的一个重要环节。本文就优化SQLSERVER查询进行一些分析。
2 优化方法2.1 索引
索引是常见的数据库对象,它的设置好坏、使用是否得当,极大地影响数据库应用程序和数据库的性能。在良好的数据库设计基础上,能有效地使用索引是SQLSERVER取得高性能的基础。如果对于一个未建立索引的表执行查询操作,SQLSERVER必须进行表扫描,从磁盘上读表的每一个数据页,从而挑选出所有符合条件的数据行。特别是当一个
表有很多行时,就会浪费大量时间,效率太低。然而在建立索引之后,SQLSERVER将根据索引的指示,直接定位到需要查询的数据行,从而加快SQLSERVER的数据检索操作。这样利用索引可以避免表扫描,并减少因查询而造成的I/O开销。
(1)簇索引
簇索引是对磁盘上实际数据重新组织,以按指定的一个或多个列的值排序。一个簇索引是一个B-树,其底层包含了表中所有的数据页,并且数据的物理存储顺序与索引顺序完全相同,亦即簇索引的数据是按照一定的物理排序方式来保存的。由于簇索引的索引页面指针指向数据页面,所以使用簇索引检索数据要比非簇索引快,而且它适用于检索连续键值。
由于数据存储于数据页中,所以只能为每个表建立一个簇索引。而且创建簇索引要求数据库有足够的空间来容纳大约1.2倍于表中实际数据的数据。在簇索引下,数据在物理上按顺序排在数据页上,重复值也排在一起,所以查询时一旦找到符合条件的第一条记录,具有相同键值或后续键值的行一定在物理上与它连在一起,而不必进一步搜索,从而收稿日期:2007-06-29
缩小了查询范围,提高了查询速度。由于每个表只能建一个簇索引,因此必须明智地选择簇索引,以下一些情况比较适合创建簇索引:
①用于范围查询的列;②用于OrderBy或GroupBy查询的列;③用于连接操作的列;④返回大量结果集的查询;⑤不经常修改的列(对经常变动的列,列值修改后,数据行必须移动到新的位置)。
(2)非簇索引
对于非簇索引,叶级页包括了到数据页和行的行定位器,而不像簇索引中那样是真正的数据。它不对表中的物理数据页进行排序。因此,创建一个非簇索引不要求必须有大的剩余空间。一个表最多可建立249个非簇索引,但要注意,表中索引数目太多,会影响到其它操作的性能,例如Up2date,Delete和Insert等。因此,不要试图使用过多的索引,一般而言,对于一个表拥有一个簇索引和2-6个非簇索引就已经足够了(数据仓库例外)。每个非簇索引提供访问数据的不同排序顺序。以下为一些创建非簇索引比较合适的场合:
①用于集合功能的列;②外部键;③返回数据量小的结果集的查询;④经常要通过在表连接中指定列的方式访问的信息,或者查询中排序和组合需要的列。
(3)复合索引
复合索引是通过两个或两个以上的列创建的键(最大列数为16列),索引值的最大长度为900字节。不要试图创建列数过多的复合索引,过多的列会影响性能并使索引键变大,这样在读取索引键时要扫描更多的数据页。在复合索引中应首先定义最可能具有唯一性的列。那么SQLSERVER何时能充分利用索引的优势,何时不能使用索引?
当对一个大型表进行操作时,如果满足下列条件,优化器就能充分利用复合索引:
①复合索引中的第一个字段或所有字段是在Where子句中引用的字段,并且包含有用的搜索参数。
②复合索引中的字段,在Where子句中不参与任何形式
・41・
辽宁省交通高等专科学校学报
的计算。
举例如下,用户guest1想要查询表table0中满足条件的记录,首先建立以前三列为索引的复合索引:
CreateIndexCol1_2_3_indexOntable0(col1,col2,col3)
则如下查询不能充分利用复合索引的优势:
Select3FromTable0Wherecol2=value2Andcol3=val2
ue3
2007年
或条件为单独的col2或col3。这类查询是很不合理的,因为它的前导列是col1,而以上查询语句没有引用col1,也就是没有利用索引。而如下查询则能充分利用复合索引的优势:
Select3Fromtable0Wherecol1=value1andcol2=val2ue2andcol3=value3
或条件为单独的col1或为col1与col2、col3的任意组合。这类查询语句使用了col1,所以查询速度很快。
(4)覆盖索引
当要查询的所有信息都包括在单独的非簇索引(也即一个复合索引)的索引项中时,即为覆盖索引。SQL不用读取数据页来满足查询,因为索引的叶级页中包含了所需的全部信息。当表的行数远远大于索引键的数目时,可明显加快查询速度。
但是由于覆盖索引的索引项较多,要占用大的空间。所以使用覆盖索引要注意权衡利弊。
(5)使用索引的注意事项
索引可以加快数据访问速度,减少I/0操作的次数,对于查询大有益处。但对于更新的操作性能会是一个障碍,这是由于在数据修改、插入或删除时需要更新索引,因此索引页的更新将增加额外的I/0操作。而且表中过多的索引可能影响到性能。创建索引时注意以下情况:
①对于行数很少的表,没有必要建立索引。当表中只有几个数据时,SQLSERVER执行表扫描的速度可能会快于索引。
②对于一个经常需要变动而决策支持操作很少的表,应尽量限制表中索引的使用。
③尽量避免使用长键作为索引列。这样可以减少数据页占用,并减少了在一次查询中SQLSERVER需要读取的数据页数目。
④不要创建SQLSERVER不使用的索引,否则该索引只会浪费空间,并且数据更新时产生不必要的开销。
⑤不能对只有很少唯一值的字段生成索引。
因此,在使用索引的时候一定要谨慎,要选择恰当的索引,尽量减少磁盘访问的次数,提高整个系统的性能。2.2 视图
(1)标准视图
视图是一种数据库对象,它是由用户从一个或多个表中建立的一个虚拟表。视图是SQL查询语句而不是用数据构造的。它可以用来控制用户对数据的访问,限制用户从表中所检索的内容,并能简化数据的显示。而且在大多数情况下用户所查询的信息,可能存储在多个表中,而对多表操作比较繁琐,那么可通过视图将所需的信息设计到一个视图中,以此来简化数据查询和处理操作。另外,视图中的数据都来
自于基表,是在视图被引用时动态生成的,使用视图可以集中、简化和定制用户的数据库显示,用户可以通过视图来访问数据,而不必直接去访问视图的基表。
在SQLSERVER中可能通过视图检索数据,对视图可以使用连接、GroupBy子句、子查询等,以及它们的任意组合来检索视图数据。
例如从Stud_Score数据表中检索成绩大于90的同学。首先建立一个视图view1,然后使用视图来检索符合条件的数据,代码如下:
CreateViewview1as
SelectnamefromStud_Scorewherescore>90
当执行这个CreateView语句时,SQLserver在数据库的系统表中创建该视图的定义。一旦创建了该视图,就可以像在其它SQL语句中使用表一样使用该视图。例如:
Select3FromView1
因此,可以把视图看作一个只包含那些指定条件行的表。当需要查看多个表中的数据时,使用视图就显得极为方便。例如要连接Stud_Score和Stud_regedit表中相关行的视图,并查看数据,代码如下:
CreateViewview2as
Selectstud_score.number,stud_score.score,stud_regedit.name
Fromstud_score,stud_regedit
Onstud_score.number=stud_regedit.numberSelect3FromView2(2)索引视图
索引视图在数据库中存储视图结果集。索引视图之后,视图的虚拟成为真实:视图包含数据。索引视图可缩短对多个表和进行多个复杂连接的视图的查询时间,来直接访问所需数据,成为跨多个表格的超索引。此外,查询优化器开始在查询中使用视图优化器,而不是直接从From子句中命名视图,这样可以从索引视图中检索数据而无需重新编码,由此为查询带来高效率。但基础表更新数据时,SQLSERVER需要更新索引视图中的数据,这个更新可能影响性能。只有当视图的结果检索速度的效率超过了修改所需的开销时,才应在视图上创建索引。
(3)分区视图
分区视图可以提高分布式数据的查询效率。在各个区域的服务器中都存有本区域仓库信息的Warehouse表,这样在本地服务器上进行查询时可以大大地提高检索的效率。使用这种方法,在进行很多查询时避免了和其它服务器通信。
但是,有些查询不仅要访问本地仓库信息,还要访问一个或多个远程仓库信息。分区视图提供了简单的解决方案,因为它是含有分区数据的表的联合。每个仓库都可根据仓库的ID来辨别属于哪个服务器。例如,SERVER1服务器的仓库的ID在10001与19999之间,SERVER2服务器的仓库的ID在20001与29999之间。下列的语句说明如何在SERVER1服务器上为仓库数据创建一个分区视图:
CreateViewAllwarehouseAs
Select3FromMydatabase.tableowner.warehouse
・42・
第9卷第3期
2007年9月
辽宁省交通高等专科学校学报
JOURNAL OF LIAONING PROVINCIAL COLLEGE OF COMMUNICATIONS
Vol.9No.3Sep.2007
文章编号:1008-3812(2007)03-043-02
谈谈C++中宏与内联函数
付
凯
(辽宁省交通高等专科学校,辽宁沈阳 110122)
摘 要 文中主要讨论了c++中宏定义与内联函数的作用和它们之间的区别。
关键词 宏定义 内联函数 编译器 预处理器中图分类号:TP312 文献标识码:A 1 宏宏定义
C++是C的超集,C++继承了C的一个重要特性就是效率,在C中提高程序运行效率的重要手段就是宏,宏可以不用普通函数的调用但使用起来就像普通函数调用一样,宏的实现采用的是预处理器而不是编译器,所以就没有了参数调用、生成汇编语言的CALL,返回参数和执行汇编语言RETURN等时间的花费,因而大大提高了程序执行的效率。当然在C++中也可以采用这种方式提高程序执行的效率。
例如:
#include Unionall Select3Fromserver2.Mydatabase.tableowner.warehouse因为本地的查询很少需要访问远端的数据,因此这种优化器大大地提高了查询的效率。例如下列语句实现了SERVER1服务器上的一个查询: Select3FromAllwarehousewherewarehouseID=10088分区视图使服务器组中的多个服务器之间可以实现并行处理,这样,数据可以分布在多个服务器之间,查询时根据需要动态合并。它提供了访问不同地址保存的数据的强大功能,但是管理和使用视图很复杂,视图生成和使用的规则很多,因此,只有遵守所有规则,才可利用其强大特性。2.3 异步查询 异步查询是远程数据库对象(RDO)的一个特征(RDO #definedoub(x)x32intmain(){for(inti=1;i<=3;i++) cout<endl; return0;} 程序运行的结果为:1doubled22doubled43doubled6 用于开发SQLSERVER数据库应用程序),它允许应用程序在等待完成长时间运行的查询时,能够执行其它任务。这样就使得用户在执行其它操作之前,不必等待查询的完成,实现并行操作。3 结束语 实现优化查询的方法还有很多。要根据具体情况来确定采用哪种查询方式,注意权衡利弊,以使数据查询性能达到最优。参考文献 [1]求是科技.SQLSERVER2000数据库管理与开发技术大全. 人民邮电出版社,2004 [2]闪四清.SQLSERVER实用简明教程.清华大学出版社,2002[3]陈永强等.SQLServer数据库企业应用系统开发.清华大学出版 社,2004 TheAnalysisofOptimizingQueryofSQLServer LiNa 〔Abstracts〕Withthedataquantity’sincreasingintheapplicationsystem,itisnecessarytoimprovequeryandaccessfunctionofdata2 basemanagementsysteminSQLserver.TheanalysisofoptimizingqueryofSQLserverisdiscussedinthepaper.〔Keywords〕index;view;asynchronousquery ・43・ 因篇幅问题不能全部显示,请点此查看更多更全内容