数据库及OLEDB类别知识汇总.doc_第1页
数据库及OLEDB类别知识汇总.doc_第2页
数据库及OLEDB类别知识汇总.doc_第3页
数据库及OLEDB类别知识汇总.doc_第4页
数据库及OLEDB类别知识汇总.doc_第5页
已阅读5页,还剩16页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

数据库及OLEDB类别知识汇总一、_variant_t_variant_t变体的成员中:bVal并不是bool型的,而是一个无符号的整型。通过SQL Server返回值时,如果是bit型的1,bVal会返回255。boolVal也不是bool型的,而是short型的。二、ADODataSetBackupADODataSetBackup.close;ADODataSetBmandtext=Select from tablename;ADODataSetBackup.open;.备份ADODataSetBackup.savetofile(备份文件名);.恢复ADODataSetRestore.loadfromfile(备份文件名);ADODataSetRestore.post;三、char和varchar的区别CHAR的长度是固定的,VARCHAR2的长度是可以变化的。比如,存储字符串“abc,对于CHAR (10),存储的字符将占10个字节(包括7个空字符),VARCHAR2 (10)只占用3个字节的长度,10只是最大值,当存储的字符小于10时,按实际长度存储。CHAR的效率比VARCHAR2的效率稍高。 目前VARCHAR是VARCHAR2的同义词。工业标准的VARCHAR类型可以存储空字符串,但是oracle不这样做,尽管它保留以后这样做的权利。Oracle自己开发了一个数据类型VARCHAR2,这个类型不是一个标准的VARCHAR,它将在数据库中varchar列可以存储空字符串的特性改为存储NULL值。如果你想有向后兼容的能力,Oracle建议使用VARCHAR2而不是VARCHAR。 CHAR与VARCHAR2是一对矛盾的统一体,两者是互补的关系。VARCHAR2比CHAR节省空间,在效率上比CHAR会稍微差一些,即要想获得效率,就必须牺牲一定的空间,这也就是我们在数据库设计上常说的“以空间换效率”。VARCHAR2虽然比CHAR节省空间,但如果一个VARCHAR2列经常被修改,而且每次被修改的数据的长度不同,这会引起“行迁移”(Row Migration)现象,造成多余的I/O,是数据库设计和调整中要尽力避免的,在这种情况下用CHAR代替VARCHAR2会更好一些。四、表结构里的默认值的设定正数:(默认值)负数:(默认值)字符串:(默认值)五、二进制字符串的提取当必须从二进制的字符串、表列中的字符串值或是字符串表达式中提取部分字符串时,有以下两种办法:一、如果提取的是以从起始字节开始的子串,那么可以利用varbinary变量来截取。二、如果提取的是中间的某一部分,则需要用SubString函数。该函数语法如下:SubString (, , )start并不是指的起始字符,而是指的起始位置。即select SubString (UserDefData, 7, 6)是指从UserDefData中取出第七个字符开始的6个字符组成的字串(712)如果不知道字符串的实际长度,只要指定让SubString函数返回的最大数目的字符号串。当SubString函数发现从(起点)到字符串尾部的长度比个字符串短时,就返回从位置到结尾时的字符串(不报告错误)。由此,可以通过同一语句来获取诸如Pcm360、Pcm360DB、Pcm360DB_1这三个结果。如果是NULL,SubString函数将返回NULL值。类似的,如果指定的比的长度还大,某些DBMS产品将返回NULL结果。另一些,例如MS-SQL Server将返回空的字符串(长度为0)。六、经典SQL语句集锦SQL分类:DDL数据定义语言(CREATE,ALTER,DROP,DECLARE) DML数据操纵语言(SELECT,DELETE,UPDATE,INSERT) DCL数据控制语言(GRANT,REVOKE,COMMIT,ROLLBACK)-备份库USE masterexec sp_addumpdevice disk, testBack, C:.BACKUP DATABASE pubs TO testBack -创建表CREATE TABLE tab_new like tab_oldCREATE TABLE tab_new ASSELECT Column1, Column 2FROM tab_old DEFINITION ONLY-修改表ALTER TABLE TableName ADD COLUMN ColumnName ElemType AllowNullALERT TABLE TableName ADD PRIMARY KEY (ColumnName)ALERT TABLE TableName DROP PRIMARY KEY (ColumnName)注1:所有DBMS中,列增加后将不能删除。注2:DB2中列增加后数据类型也不能改变,唯一能改变的是增加varchar类型的长度。-创建索引CREATE UNIQUE CLUSTERED | NONCLUSTERED INDEX IndexNameON TableName (Column1, Column2)注:索引是不可更改的,想更改必须删除重新建。-创建和删除视图CREATE VIEW ViewName AS SELECTDROP VIEW ViewNameUNION运算符:UNION运算符通过组合其他两个结果表(例如TABLE1和TABLE2)并消去表中任何重复行而派生出一个结果表。当ALL随UNION一起使用时,不消除重复行。两种情况下派生表的每一行不是来自TABLE1就是来自TABLE2。EXCEPT运算符:EXCEPT运算符通过包括所有在TABLE1中但不在TABLE2中的行并消除所有重复行而派生出一个结果表。当ALL随EXCEPT一起使用时(EXCEPT ALL),不消除重复行。INTERSECT运算符:INTERSECT运算符通过只包括TABLE1和TABLE2中都有的行并消除所有重复行而派生出一个结果表。当ALL随INTERSECT一起使用时(INTERSECT ALL),不消除重复行。注:使用运算符的几个查询结果行必须是一致的。LEFT OUTER JOIN:结果集既包括连接表的匹配行,也包括左连接表的所有行。RIGHT OUTER JOIN:结果集既包括连接表的匹配连接行,也包括右连接表的所有行。FULL OUTER JOIN:不仅包括符号连接表的匹配行,还包括两个连接表中的所有记录。复制表(只复制结构。源表名:a,新表名:b)(Access可以用)法一:SELECT * INTO b FROM a WHERE 11法二:SELECT TOP 0 * INTO b FROM a拷贝表(拷贝数据。源表名:a,目标表名:b)(Access可以用)INSERT INTO b (a, b, c) SELECT d, e, f FROM b跨数据库之间表的拷贝(数据使用绝对路径)(Access可以用)INSERT INTO b (a, b, c) SELECT d, e, f FROM b IN &Server.MapPath(.)&data.mdb & WHERE子查询(表名1:a 表名2:b)SELECT a, b, c FROM a WHERE a IN (SELECT d FROM b)SELECT a, b, c FROM a WHERE a IN (1, 2, 3)外连接查询(表名1:a 表名2:b)SELECT a.a, a.b, a.c, b.c, b.d, b.f FROM a LEFT OUT JOIN b ON a.a = b.c在线视图查询(表名1:a )SELECT * FROM (SELECT a, b, c FROM a)T WHERE t.a 1BETWEEN限制查询数据范围时包括了边界值,NOT BETWEEN不包括边界值。SELECT * FROM table1 WHERE time BETWEEN time1 AND time2SELECT a, b, c FROM table1 WHERE a NOT BETWEEN a1 AND a2Conn.Execute说明Execute方法该方法用于执行SQL语句。根据SQL语句执行后是否返回记录集,该方法的使用格式分为以下两种:1执行SQL查询语句时,将返回查询得到的记录集。用法为:Set 对象变量名=连接对象.Execute(SQL 查询语言)Execute方法调用后,会自动创建记录集对象,并将查询结果存储在该记录对象中,通过Set方法,将记录集赋给指定的对象保存,以后对象变量就代表了该记录集对象。2执行SQL的操作性语言时,没有记录集的返回。此时用法为:连接对象.Execute SQL 操作性语句 , RecordAffected, OptionRecordAffected 为可选项,此出可放置一个变量,SQL语句执行后,所生效的记录数会自动保存到该变量中。通过访问该变量,就可知道SQL语句队多少条记录进行了操作。Option 可选项,该参数的取值通常为adCMDText,它用于告诉ADO,应该将Execute方法之后的第一个字符解释为命令文本。通过指定该参数,可使执行更高效。BeginTrans、RollbackTrans、CommitTrans方法这三个方法是连接对象提供的用于事务处理的方法。BeginTrans用于开始一个事物;RollbackTrans用于回滚事务;CommitTrans用于提交所有的事务处理结果,即确认事务的处理。事务处理可以将一组操作视为一个整体,只有全部语句都成功执行后,事务处理才算成功;若其中有一个语句执行失败,则整个处理就算失败,并恢复到处里前的状态。BeginTrans和CommitTrans用于标记事务的开始和结束,在这两个之间的语句,就是作为事务处理的语句。判断事务处理是否成功,可通过连接对象的Error集合来实现,若Error集合的成员个数不为0,则说明有错误发生,事务处理失败。Error集合中的每一个Error对象,代表一个错误信息。七、哪种命令可以用来压缩数据库容量数据库在使用一段时间后,时常会出现因数据删除而造成数据库中空闲空间太多的情况,这时就需要减少分配给数据库文件和事务日志文件的磁盘空间,以免浪费磁盘空间。当数据库中没有数据时,可以修改数据库文件属性直接改变其占用空间,但当数据库中有数据时,这样做会破坏数据库中的数据,因此需要使用压缩的方式来缩减数据库空间。可以在数据库属性选项中选择“Auto shrink”选项,让系统自动压缩数据库,也可以用人工的方法来压缩。人工压缩数据库可以用Enterprise Manager 压缩数据库,也可以用Transact-SQL 命令压缩数据库:DBCC SHRINKDATABASE:对数据库进行压缩。命令语法如下:DBCC SHRINKDATABASE (database_name , target_percent, NOTRUNCATE | TRUNCATEONLY )各参数说明如下: target_percent:指定将数据库压缩后,未使用的空间占数据库大小的百分之几。如果指定的百分比过大,超过了压缩前未使用空间所占的比例,则数据库不会被压缩。并且压缩后的数据库不能比数据库初始设定的容量小。NOTRUECATE:将数据库缩减后剩余的空间保留在数据库,中不返还给操作系统。如果不选择此选项,则剩余的空间返还给操作系统。 TRUNCATEONLY:将数据库缩减后剩余的空间返还给操作系统。使用此命令时SQL Server 将文件缩减到最后一个文件分配,区域但不移动任何数据文件。选择此项后,target_percent 选项就无效了。DBCC SHRINKDATABASE (mytest, 20):数据库mytest 的未使用空间为数据库大小的20%。运行结果如下:DBCC execution completed. If DBCC printed error messages, contact your system administrator. DBCC SHRINKFILE:对数据库中指定的文件进行压缩。其语法如下:DBCC SHRINKFILE (file_name | file_id , target_size | , EMPTYFILE | NOTRUNCATE | TRUNCATEONLY )各参数说明如下:file_id指定要压缩的文件的鉴别号(Identification number, 即ID)。文件的ID 号可以通过 FILE_ID()函数或如本章前面所讲述的Sp_helpdb 系统存储过程来得到。 target_size指定文件压缩后的大小。以MB 为单位。如果不指定此选项,SQL Server 就会尽最大可能地缩减文件。EMPTYFILE指明此文件不再使用,将移动所有在此文件中的数据到同一文件组中的其它文件中去。执行带此参数的命令后,此文件就可以用ALTER DATABASE 命令来删除了。 其余参数NOTRUNCATE 和TRUNCATEONLY 与DBCC SHRINKDATABASE 命令中的含义相同。例: 压缩数据库mydb 中的数据库文件mydb_data2 的大小到1MB。USE mydbDBCC SHRINKFILE (mydb_data2, 1)八、什么是聚集索引,什么是非聚集索引,什么又是主键?使用聚集索引:聚集索引确定表中数据的物理顺序。聚集索引类似于电话簿,后者按姓氏排列数据。由于聚集索引规定数据在表中的物理存储顺序,因此一个表只能包含一个聚集索引。但该索引可以包含多个列(组合索引),就像电话簿按姓氏和名字进行组织一样。聚集索引对于那些经常要搜索范围值的列特别有效。使用聚集索引找到包含第一个值的行后,便可以确保包含后续索引值的行在物理相邻。例如,如果应用程序执行的一个查询经常检索某一日期范围内的记录,则使用聚集索引可以迅速找到包含开始日期的行,然后检索表中所有相邻的行,直到到达结束日期。这样有助于提高此类查询的性能。同样,如果对从表中检索的数据进行排序时经常要用到某一列,则可以将该表在该列上聚集(物理排序),避免每次查询该列时都进行排序,从而节省成本。当索引值唯一时,使用聚集索引查找特定的行也很有效率。例如,使用唯一雇员 ID 列 emp_id 查找特定雇员的最快速的方法,是在 emp_id 列上创建聚集索引或 PRIMARY KEY 约束。如果该表上尚未创建聚集索引,且在创建 PRIMARY KEY 约束时未指定非聚集索引,PRIMARY KEY 约束会自动创建聚集索引。也可以在 lname(姓氏)列和 fname(名字)列上创建聚集索引,因为雇员记录常常是按姓名而不是按雇员 ID 分组和查询的。使用非聚集索引:非聚集索引与课本中的索引类似。数据存储在一个地方,索引存储在另一个地方,索引带有指针指向数据的存储位置。索引中的项目按索引键值的顺序存储,而表中的信息按另一种顺序存储(这可以由聚集索引规定)。如果在表中未创建聚集索引,则无法保证这些行具有任何特定的顺序。与使用书中索引的方式相似,Microsoft® SQL Server™ 2000 在搜索数据值时,先对非聚集索引进行搜索,找到数据值在表中的位置,然后从该位置直接检索数据。这使非聚集索引成为精确匹配查询的最佳方法,因为索引包含描述查询所搜索的数据值在表中的精确位置的条目。如果基础表使用聚集索引排序,则该位置为聚集键值;否则,该位置为包含行的文件号、页号和槽号的行 ID (RID)。例如,对于在 emp_id 列上有非聚集索引的表,如要搜索其雇员 ID (emp_id),SQL Server 会在索引中查找这样一个条目,该条目精确列出匹配的 emp_id 列在表中的页和行,然后直接转到该页该行。多个非聚集索引:有些书籍包含多个索引。例如,一本介绍园艺的书可能会包含一个植物通俗名称索引,和一个植物学名索引,因为这是读者查找信息的两种最常用的方法。对于非聚集索引也是如此。可以为在表中查找数据时常用的每个列创建一个非聚集索引。注意事项:在创建非聚集索引之前,应先了解您的数据是如何被访问的。可考虑将非聚集索引用于: 包含大量非重复值的列,如姓氏和名字的组合(如果聚集索引用于其它列)。如果只有很少的非重复值,如只有 1 和 0,则大多数查询将不使用索引,因为此时表扫描通常更有效。 不返回大型结果集的查询。 返回精确匹配的查询的搜索条件(WHERE 子句)中经常使用的列。 经常需要联接和分组的决策支持系统应用程序。应在联接和分组操作中使用的列上创建多个非聚集索引,在任何外键列上创建一个聚集索引。 在特定的查询中覆盖一个表中的所有列。这将完全消除对表或聚集索引的访问。 PRIMARY KEY 约束:表中经常有一个列或列的组合,其值能唯一地标识表中的每一行。这样的一列或多列称为表的主键,通过它可强制表的实体完整性。当创建或更改表时可通过定义 PRIMARY KEY 约束来创建主键。一个表只能有一个 PRIMARY KEY 约束,而且 PRIMARY KEY 约束中的列不能接受空值。由于 PRIMARY KEY 约束确保唯一数据,所以经常用来定义标识列。当为表指定 PRIMARY KEY 约束时,Microsoft® SQL Server™ 2000 通过为主键列创建唯一索引强制数据的唯一性。当在查询中使用主键时,该索引还可用来对数据进行快速访问。如果 PRIMARY KEY 约束定义在不止一列上,则一列中的值可以重复,但 PRIMARY KEY 约束定义中的所有列的组合的值必须唯一。如下图所示,titleauthor 表中的 au_id 和 title_id 列组成该表的组合 PRIMARY KEY 约束,以确保 au_id 和 title_id 的组合唯一。什么是聚集索引和非聚集索引SQL SERVER提供了两种索引:聚集索引(clustered index,也称聚类索引、簇集索引)和非聚集索引(nonclustered index,也称非聚类索引、非簇集索引)。其实,我们的汉语字典的正文本身就是一个聚集索引。比如,我们要查“安”字,就会很自然地翻开字典的前几页,因为“安”的拼音是“an”,而按照拼音排序汉字的字典是以英文字母“a”开头并以“z”结尾的,那么“安”字就自然地排在字典的前部。如果您翻完了所有以“a”开头的部分仍然找不到这个字,那么就说明您的字典中没有这个字;同样的,如果查“张”字,那您也会将您的字典翻到最后部分,因为“张”的拼音是“zhang”。也就是说,字典的正文部分本身就是一个目录,您不需要再去查其他目录来找到您需要找的内容。我们把这种正文内容本身就是一种按照一定规则排列的目录称为“聚集索引”。 如果您认识某个字,您可以快速地从自动中查到这个字。但您也可能会遇到您不认识的字,不知道它的发音,这时候,您就不能按照刚才的方法找到您要查的字,而需要去根据“偏旁部首”查到您要找的字,然后根据这个字后的页码直接翻到某页来找到您要找的字。但您结合“部首目录”和“检字表”而查到的字的排序并不是真正的正文的排序方法,比如您查“张”字,我们可以看到在查部首之后的检字表中“张”的页码是672页,检字表中“张”的上面是“驰”字,但页码却是63页,“张”的下面是“弩”字,页面是390页。很显然,这些字并不是真正的分别位于“张”字的上下方,现在您看到的连续的“驰、张、弩”三字实际上就是他们在非聚集索引中的排序,是字典正文中的字在非聚集索引中的映射。我们可以通过这种方式来找到您所需要的字,但它需要两个过程,先找到目录中的结果,然后再翻到您所需要的页码。我们把这种目录纯粹是目录,正文纯粹是正文的排序方式称为“非聚集索引”。 通过以上例子,我们可以理解到什么是“聚集索引”和“非聚集索引”。进一步引申一下,我们可以很容易的理解:每个表只能有一个聚集索引,因为目录只能按照一种方法进行排序。何时使用聚集索引或非聚集索引下面的表总结了何时使用聚集索引或非聚集索引(很重要): 动作描述使用聚集索引使用非聚集索引列经常被分组排序应应返回某范围内的数据应不应一个或极少不同值不应不应小数目的不同值应不应大数目的不同值不应应频繁更新的列不应应外键列应应主键列应应频繁修改索引列不应应事实上,我们可以通过前面聚集索引和非聚集索引的定义的例子来理解上表。如:返回某范围内的数据一项。比如您的某个表有一个时间列,恰好您把聚合索引建立在了该列,这时您查询2004年1月1日至2004年10月1日之间的全部数据时,这个速度就将是很快的,因为您的这本字典正文是按日期进行排序的,聚类索引只需要找到要检索的所有数据中的开头和结尾数据即可;而不像非聚集索引,必须先查到目录中查到每一项数据对应的页码,然后再根据页码查到具体内容。索引是如何工作的?改善SQL语句 很多人不知道SQL语句在SQL SERVER中是如何执行的,他们担心自己所写的SQL语句会被SQL SERVER误解。比如: 执行SELECT * FROM Table1 WHERE Name = ZhangSan AND tID 10000和执行SELECT * FROM Table1 WHERE tID 10000 AND Name = ZhangSan一些人不知道以上两条语句的执行效率是否一样,因为如果简单的从语句先后上看,这两个语句的确是不一样,如果tID是一个聚合索引,那么后一句仅仅从表的10000条以后的记录中查找就行了;而前一句则要先从全表中查找看有几个Name = ZhangSan的,而后再根据限制条件条件tID10000来提出查询结果。 事实上,这样的担心是不必要的。SQL SERVER中有一个“查询分析优化器”,它可以计算出WHERE子句中的搜索条件并确定哪个索引能缩小表扫描的搜索空间,也就是说,它能实现自动优化。 虽然查询优化器可以根据WHERE子句自动的进行查询优化,但大家仍然有必要了解一下“查询优化器”的工作原理,如非这样,有时查询优化器就会不按照您的本意进行快速查询。 在查询分析阶段,查询优化器查看查询的每个阶段并决定限制需要扫描的数据量是否有用。如果一个阶段可以被用作一个扫描参数(SARG),那么就称之为可优化的,并且可以利用索引快速获得所需数据。 SARG的定义:用于限制搜索的一个操作,因为它通常是指一个特定的匹配,一个值得范围内的匹配或者两个以上条件的AND连接。形式如下: 列名 操作符 或 操作符列名列名可以出现在操作符的一边,而常数或变量出现在操作符的另一边。如:Name=张三价格5000 50005000如果一个表达式不能满足SARG的形式,那它就无法限制搜索的范围了,也就是SQL SERVER必须对每一行都判断它是否满足WHERE子句中的所有条件。所以一个索引对于不满足SARG形式的表达式来说是无用的。 介绍完SARG后,我们来总结一下使用SARG以及在实践中遇到的和某些资料上结论不同的经验: 1、Like语句是否属于SARG取决于所使用的通配符的类型如:name like 张%,这就属于SARG而:name like %张,就不属于SARG。原因是通配符%在字符串的开通使得索引无法使用。2、or 会引起全表扫描。Name = 张三 AND 价格5000,符合SARG,Name = 张三 OR 价格5000,不符合SARG。原因是使用or会引起全表扫描。 3、非操作符、函数引起的不满足SARG形式的语句。不满足SARG形式的语句最典型的情况就是包括非操作符的语句,如:NOT、!=、!、NOT EXISTS、NOT IN、NOT LIKE等,另外还有函数。下面就是几个不满足SARG形式的例子:ABS(价格)5000,SQL SERVER也会认为是SARG,SQL SERVER会将此式转化为:价格5000/2但我们不推荐这样使用,因为有时SQL SERVER不能保证这种转化与原始表达式是完全等价的。 5、IN 的作用相当与OR 的语句: SELECT * FROM Table1 WHERE tid IN (2, 3)和SELECT * FROM Table1 WHERE tid = 2 OR tid = 3是一样的,都会引起全表扫描,如果tid上有索引,其索引也会失效。 SQL优化1:EXISTS 和 IN 的执行效率是一样的。很多资料上都显示说,EXISTS要比IN的执行效率要高,同时应尽可能的用NOT EXISTS来代替NOT IN。但事实上,我试验了一下,发现无论带不带NOT,二者的执行效率都是一样的。因为涉及子查询,我们试验这次用SQL SERVER自带的pubs数据库。运行前可以把SQL SERVER的statistics I/O状态打开:SELECT title, price FROM titles where title_id IN(SELECT title_id FROM sales WHERE qty 30)执行结果为: 表 sales。扫描计数 18,逻辑读 56 次,物理读 0 次,预读 0 次。表 titles。扫描计数 1,逻辑读 2 次,物理读 0 次,预读 0 次。SELECT title, price FROM titles WHERE EXISTS(SELECT * FROM sales WHERE sales.title_id = titles.title_id AND qty 30)执行结果为: 表 sales。扫描计数 18,逻辑读 56 次,物理读 0 次,预读 0 次。 表 titles。扫描计数 1,逻辑读 2 次,物理读 0 次,预读 0 次。从此可以看到用EXISTS和用IN的执行效率是一样的。SQL优化2:用函数CHARINDEX()和前面加通配符%的LIKE执行效率一样。前面,我们谈到,如果在LIKE前面加上通配符%,那么将会引起全表扫描,所以其执行效率是低下的。但有的资料介绍说,用函数CHARINDEX()来代替LIKE速度会有大的提升,经我试验,发现这种说明也是错误的:SELECT gid, title, FaRiQi, reader FROM TGongWenWHERE CHARINDEX (刑侦支队, reader) 0 AND FaRiQi 2004-5-5用时:7秒,另外:扫描计数 4,逻辑读 7155 次,物理读 0 次,预读 0 次。SELECT gid, title, FaRiQi, reader FROM TGongWenWHERE reader LIKE %刑侦支队% AND FaRiQi 2004-5-5用时:7秒,另外:扫描计数 4,逻辑读 7155 次,物理读 0 次,预读 0 次。 SQL优化3:UNION并不绝对比OR的执行效率高。前面已经谈到了在WHERE子句中使用OR会引起全表扫描。一般的,我所见过的资料都是推荐这里用UNION来代替OR。事实证明,这种说法对于大部分都是适用的。SELECT gid, FaRiQi, NeiBuYongHu, reader, title FROM TGongWenWHERE FaRiQi = 2004-9-16 OR gid 9990000用时:68秒。扫描计数 1,逻辑读 404008 次,物理读 283 次,预读 392163 次。SELECT gid, FaRiQi, NeiBuYongHu, reader, title FROM TGongWenWHERE FaRiQi = 2004-9-16 UNIONSELECT gid, FaRiQi, NeiBuYongHu, reader, title FROM TGongWenWHERE Gid 9990000用时:9秒。扫描计数 8,逻辑读 67489 次,物理读 216 次,预读 7499 次。 看来,用UNION在通常情况下比用OR的效率要高的多。但经过试验,笔者发现如果OR两边的查询列是一样的话,那么用UNION则反倒和用OR的执行速度差很多,虽然这里UNION扫描的是索引,而OR扫描的是全表。SELECT gid, FaRiQi, NeiBuYongHu, reader, title FROM TGongWenWHERE FaRiQi = 2004-9-16 OR FaRiQi = 2004-2-5用时:6423毫秒。扫描计数 2,逻辑读 14726 次,物理读 1 次,预读 7176 次。SELECT gid, FaRiQi, NeiBuYongHu, reader, title FROM TGongWenWHERE FaRiQi = 2004-9-16 UNIONSELECT gid, FaRiQi, NeiBuYongHu, reader, title FROM TGongWenWHERE FaRiQi = 2004-9-16用时:11640毫秒。扫描计数 8,逻辑读 14806 次,物理读 108 次,预读 1144 次。 SQL优化4:字段提取要按照“需多少、提多少”的原则,避免“ SELECT * ” 。试验: SELECT TOP 10000 gid, FaRiQi, reader, titleFROM TGongWen ORDER BY gid DESC用时:4673毫秒SELECT TOP 10000 gid, FaRiQi, titleFROM TGongWen ODER BY gid DESC用时:1376毫秒SELELCT TOP 10000 gid, FaRiQi FROM TGongWen ORDER BY gid DESC用时:80毫秒 由此看来,我们每少提取一个字段,数据的提取速度就会有相应的提升。提升的速度还要看您舍弃的字段的大小来判断。 SQL优化5:COUNT(*)不比COUNT(字段)慢。某些资料上说:用*会统计所有列,显然要比一个世界的列名效率低。这种说法其实是没有根据的。我们来看:SELECT COUNT(*) FROM TGongWen用时:1500毫秒SELECT COUNT(gid) FROM TGongWen用时:1483毫秒SELECT COUNT(FaRiQi) FROM TGongWen用时:3140毫秒SELECT COUNT(title) FROM TGongWen用时:52050毫秒 从以上可以看出,如果用COUNT(*)和用COUNT(主键)的速度是相当的,而COUNT(*)却比其他任何除主键以外的字段汇总速度要快,而且字段越长,汇总的速度就越慢。我想,如果用COUNT(*), SQL SERVER可能会自动查找最小字段来汇总的。当然,如果您直接写COUNT(主键)将会来的更直接些。 但是,COUNT(列名)不会计算列值为NULL的行。根据资料记录,之所以用COUNT(*)速度比较快,是因为在部分DBMS中,系统表中存储了表行数,COUNT(*)将很快地返回表行计数。如果选择单列且允许为NULL的列时,就不能直接提取了,还要从头到尾的读取表并对物理表中的行计数。在那些不在系统表中维护行计数的系统上,通过将索引的NOT NULL约束的列作为参数使用COUNT(),则可能更快地对表行计数。SQL优化6:ORDER BY按聚集索引列排序效率最高。例:(gid是主键,FaRiQi是聚合索引列):SELECT TOP 10000 gid, FaRiQi, reader, title FROM TGongWen用时:196 毫秒。 扫描计数 1,逻辑读 289 次,物理读 1 次,预读 1527 次。SELECT TOP 10000 gid, FaRiQi, reader, title FROM TGongWenORDER BY gid ASC用时:4720毫秒。 扫描计数 1,逻辑读 41956 次,物理读 0 次,预读 1287 次。SELECT TOP 10000 gid, FaRiQi, reader, title FROM TGongWenODER BY gid DESC用时:4736毫秒。 扫描计数 1,逻辑读 55350 次,物理读 10 次,预读 775 次。SELECT TOP 10000 gid, FaRiQi, reader, title FROM TGongWenORDER BY FaRiQi ASC用时:173毫秒。 扫描计数 1,逻辑读 290 次,物理读 0 次,预读 0 次。SELECT TOP 10000 gid, FaRiQi, reader, title FROM TGongWenORDER BY FaRiQi DESC用时:156毫秒。 扫描计数 1,逻辑读 289 次,物理读 0 次,预读 0 次。 从以上我们可以看出,不排序的速度以及逻辑读次数都是和“order by 聚集索引列” 的速度是相当的,但这些都比“order by 非聚集索引列”的查询速度是快得多的。同时,按照某个字段进行排序的时候,无论是正序还是倒序,速度是基本相当的。 SQL优化7:高效的TOP。事实上,在查询和提取超大容量的数据集时,影响数据库响应时间的最大因素不是数据查找,而是物理的I/0操作。如:SELECT TOP 10 * FROM( SELECT TOP 10000 gid, FaRiQi, title FROM TGongWENWHERE NeiBuYongHu = 办公室ODER BY gid DESC ) AS aODER BY gid ASC这条语句,从理论上讲,整条语句的执行时间应该比子句的执行时间长,但事实相反。因为,子句执行后返回的是10000条记录,而整条语句仅返回10条语句,所以影响数据库响应时间最大的因素是物理I/O操作。而限制物理I/O操作此处的最有效方法之一就是使用TOP关键词了。TOP关键词是SQL SERVER中经过系统优化过的一个用来提取前几条或前几个百分比数据的词。经笔者在实践中的应用,发现TOP确实很好用,效率也很高。但这个词在另外一个大型数据库ORACLE中却没有,这不能说不是一个遗憾,虽然在ORACLE中可以用其他方法(如:rownumber)来解决。在以后的关于“实现千万级数据的分页显示存储过程”的讨论中,我们就将用到TOP这个关键词。到此为止,我们上面讨论了如何实现从大容量的数据库中快速地查询出您所需要的数据方法。当然,我们介绍的这些方法都是“软”方法,在实践中,我们还要考虑各种“硬”因素,如:网络性能、服务器的性能、操作系统的性能,甚至网卡、交换机等。九、卸载SQL Server 2005在卸载Visual Studio 2005 时,添加/删除程序 里面有许多的安装文件,此时如果没有先卸载SQL Server 2005,而先卸载.Net Framework(提示:卸载.net Framework的得安版本从高到低的顺序,这时SQL Server 2005就无法卸载。删除Program files 下面的 Microsoft SQL Server 文件夹也没有作用。重新安装提示数据库实例已经存在,请重新选择另一个实例名称。 停用Windows下的数据库服务:SQL Server (MSSQLSERVER)SQL Server Agent (MSSQLSERVERSQL Server FullText Search (MSSQLSERVER)SQL Server BrowserSQL Server VSS Writer等。进入注册表HKEY_LOCAL_MACHINESYSTEMCurrentControlSetServices,找到停用的SQL Server相关服务注册表项,将其删除。进入注册表HKEY_LOCAL_MACHINESOFTWAREMicrosoft,找到Microsoft SQL Server、Microsoft SQL Server 2005 Redist、MSSQLServer注册表项,将其删除。重启计算机。附:如果安装SQL Server2005 提示SQLXML4安装出错,此时可进入添加/删除程序 将已安装过的SQLXML4删除,再重新安装SQL Server 2005,问题解决。(此问题是因为SQL Server 2005所带的SQLXML4版本问题引起的)。 另:曾经碰到在Window2003 SP2下无法安装SQL Server 2005,如果尝试其它的方法都无法解决,那么此问题很可能是因为Winodws Installer MSXML 6.0 Parser 6.00.3883.8 引起的,可到网上下载Winodws Installer Clean Up 来清除此项。十、用户自定义函数(User Defined Functions)SQL Server 2000除了使用系统提供的函数外,用户还可以根据需要自定义函数。用户自定义函数(User Defined Functions)是SQL Server 2000 新增的数据库对象,是SQL Server 的一大改进。用户自定义函数不能用于执行一系列改变数据库状态的操作,但它可以像系统函数一样在查询或存储过程等的程序段中使用,也可以像存储过程一样通过EXECUTE 命令来执行。用户自定义函数中存储了一个Transact-SQL 例程,可以返回一定的值。在SQL Server 2000 中根据函数返回值形式的不同将用户自定义函数分为三种类型: 标量型函数(Scalar functions):标量型函数返回一个确定类型的标量值其返回值类型为除TEXT、 NTEXT、 IMAGE、CURSOR、 TIMESTAMP 和TABLE 类型外的其它数据类型。函数体语句定义在BEGIN-END语句内,其中包含了可以返回值的Transact-SQL 命令。 内联表值型函数(Inline table-valued functions):内联表值型函数以表的形式返回一个返回值,即它返回的是一个表内联表值型函数没有由BEGIN-END 语句括起来的函数体。其返回的表由一个位于RETURN 子句中的SELECT 命令段从数据库中筛选出来。内联表值型函数功能相当于一个参数化的视图。 多声明表值型函数(Multi-statement table-valued functions):多声明表值型函数可以看作标量型和内联表值型函数的结合体。它的返回值是一个表,但它和标量型函数一样有一个用BEGIN-END 语句括起来的函数体,返回值的表中的数据是由函数体中的语句插入的。由此可见,它可以进行多次查询,对数据进行多次筛选与合并,弥补了内联表值型函数的不足。 创建标量型用户自定义函数:CREATE FUNCTION owner_name. function_name ( parameter_name AS scalar_parameter_data_type = default ,.n ) RETURNS scalar_return_data_type WITH , .n AS BEGINfunction_bodyRETURN scalar_expressionEND各参数说明如下:owner_name:指定用户自定义函数的所有者。 function_name:指定用户自定义函数的名称。database_name.owner_name.function_name 应是惟一的。parameter_name:定义一个或多个参数的名称。一个函数最多可以定义1024 个参数每个参数前用“”符号标明。参数的作用范围是整个函数。参数只能替代常量,不能替代表名、列名或其它数据库对象的名称。用户自定义函数不支持输出参数

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论