- 帖子
- 128
- 主題
- 13
- 精華
- 1
- 積分
- 118
- 點名
- 0
- 作業系統
- WinXP
- 軟體版本
- Office2003
- 閱讀權限
- 50
- 性別
- 男
- 來自
- 四川成都邛崃
- 註冊時間
- 2010-9-13
- 最後登錄
- 2017-5-12
|
2#
發表於 2010-9-13 18:32
| 只看該作者
三、构造和提交查询
在构造查询的时候,要搞清楚为什么必须这么做、为什么不能那么做是一个很复杂的问题。然而,一些基本的指导方针能够让构造高效查询的过程更加流畅、轻松。一般地,你不应该让查询浪费服务器时间。下面几个技巧能够帮助你构造出更好、更高效的查询。
不要强制SQL Server每次执行查询的时候重新编译和构造查询执行计划。避免这种重复操作的一种简单方法是使用带有参数的存储过程。注意尽量不要使用ADO Command对象的Prepare属性——有时它不能正确工作。如果使用存储过程,你还可以通过消除不必要的“受影响行数”返回值进一步提高ADO性能——只需在存储过程中加入SET NOCOUNT ON就可以了。
尽量减少与服务器的通信次数。如果你有几个相关的操作要执行,请把它们合并为一个存储过程,或者是一个可以在服务器上作为脚本执行的复合查询。避免使用方法(比如Refresh)和不适当的Parameters集合引用,它们会强制ADO增加额外的服务器通信过程。
在客户机/服务器应用中,只构造Command对象一次,而不是每次使用Command对象的时候重新构造。你可以重新设置Command的参数值,然后在需要时执行它。
当查询返回的不是一个记录集时,确保使用了adExecuteNoRecords选项,告诉ADO越过所有那些用来接收和构造记录集(Recordset格式)的代码。你可以把adExecuteNoRecords选项传递给Execute方法,或把它作为Command的选项。
执行返回简单记录集的存储过程时,不要使用Command对象。所有的存储过程(以及Command对象)可以作为Connection对象的COM方法出现。让存储过程作为Connection对象的方法出现有着显著的性能优势,同时它也简化了代码。尽管这种技术对于那些有Return Status值或Output参数的存储过程没有什么帮助,但对于动作查询(INSERT、DELETE等)以及那些返回一个或多个记录的查询来说,这种技术很有用。把存储过程作为Connection的方法之后,你可以用方法参数的形式传入存储过程的输入参数;如果调用存储过程返回了一个记录集,你可以通过方法调用中最后一个参数引用该Recordset。例如,下面的ADO语句执行一个名为“Fred”的存储过程,Fred存储过程有两个输入参数,返回一个Recordset:
MyConnection.Fred "InputArg1", 2, myRecordset
编写代码的时候,不要寄希望于VB的自动完成功能会把存储过程或Command对象名字视为合法的Connection对象的方法。在正式运行之前,COM不会解析这类名字。
除非绝对必要,否则不要返回记录集。当正在执行的查询返回记录时,ADO就会构造一个Recordset对象。构造Recordset对象的开销很大,因此你应该尽量避免使用Recordset对象。注意有时候执行查询虽然返回结果,但不是返回记录。例如,你可以通过Return Status参数返回整数值。另外,你可以返回Output参数来替代需要构造Recordset对象的记录集,SQL Server允许返回的Output参数多达1000个。
只要有可能,请用动作查询(INSERT,UPDATE,DELETE和执行这些操作的存储过程)替代可更新的Recordset游标。此时,你应该使用Execute方法和它的adExecuteNoRecords选项,确保ADO能够知道查询不需要构造Recordset对象。
除非必要,否则不要请求服务器进行排序。大多数情况下,对于一个适度大小的Recordset对象,当它被发送到客户端之后,排序速度将更快。另外,如果让ADO客户程序排序Recordset中的记录,则客户应用程序能够按照用户选择的次序排序,从而提高了灵活性。
在编写查询之前了解索引的结构。创建合适的索引,调整查询的语法以利用这些索引,你将能够提高记录提取的速度。Query Analyzer能够帮助你决定是否有必要添加更多的索引。
不要一次性返回太多的记录。很多时候,容量太大的记录集会严重地影响应用程序的性能。只返回那些当前你需要的记录,如果客户程序需要更多的记录,则以后随时提取。通过带有参数的WHERE子句,或者灵活地运用TOP N查询,限制查询的范围。
不要返回太多的列。避免使用SELECT *。SELECT *语句告诉SQL Server返回所有的列,不管实际存在的列有多少。只选择那些你需要的列,这样,当有人为表增加了更多的列时,你不会得到大得出奇的结果集。
避免使用游标。如果你必须使用游标,那么不要使用那些所需资源数量超过必要的游标类型。如果没有必要,不要要求游标提供滚动、更新和数据缓冲能力。
详细地告诉ADO你想要它做些什么。打开Recordset或者构造Command对象时,不要忘了设置CommandType选项。它避免了ADO“猜测”你的意图,你将能够减少与服务器的通信,而且使得代码更加稳定。
另外,学习使用诊断工具,测定运行在服务器上的代码和应用程序的代码占用了多少时间——以及这些时间花在哪里。在这方面,SQL Server Profiler是一个宝贵的工具。它能够阐明你的代码在要求服务器做些什么,能够在草率构造的查询中或对于错误选择的命令属性突出显示。另外,Query Analyzer还能够用图示的方式显示出SQL Server将如何执行查询,提出改进查询的建议,帮助你调整查询。Query Analyzer甚至还能够执行它提出的建议(例如,添加或者删除索引),你只需点击一下按钮就可以完成。 |
|