April 2004
Part I - 正确的使用数据库MetaData方法
Part II - 获取需要的数据
Part III - 选用最佳性能的功能
介绍
John Goodson 是一名JDBC专家组成员,也是DataDirect Technologies公司的副总裁. |
开发一个注重性能的JDBC应用程序不是一件容易的事. 当你的代码运行很慢的时候JDBC驱动程序并不会抛出异常告诉你.
本系列的性能提示将为改善JDBC应用程序的性能介绍一些基本的指导原则,这其中的原则已经被许多现有的JDBC应用程序编译运行并验证过。 这些指导原则包括:
-
正确的使用数据库MetaData方法
-
只获取需要的数据
-
选用最佳性能的功能
-
管理连接和更新
以下这些一般性原则可以帮助你解决一些公共的JDBC系统的性能问题.
获取数据
要有效的获取数据,就只需返回你需要的数据, 以及很多用效的方法. 本节的指导原则将帮助你使用JDB获取数据时优化系统性能.
获取长数据
如非必要, 应用程序不应请求长的数据, 因为长的数据通过网络传输会非常慢和消耗资源.
大多数用户并不想看到大堆的数据. 如果用户不想处理这些长数据, 那么程序应能够再次查询数据库, 在SELECT子句中指定需要的列名. 这种方式允许一般用户获取结果集而不用消耗昂贵的网络流量.
虽然最好的方式是不要将长数据包括在SELECT子句的列名中,但还是有一些应用程序在发送查询给JDBC驱动程序时并没有在SELECT子句中明确指出列名 (确切一点, 有些程序发送这样的查询: select * from
例如,看以下的JDBC代码:
...). 如果SELECT子句的列名中包含长数据, 许多JDBC驱动程序必须在查询时重新获取数据, 甚至在ResultSet中这些长数据并没有被程序用到. 在可能情况下,开发者应该试着去实现一种不需获取所有列数据的方法.
ResultSet rs = stmt.executeQuery (
"select * from Employees where SSID = '999-99-2222'");
rs.next();
string name = rs.getString (4); |
要记住JDBC驱动程序没有知觉. 当查询被执行时它不知道哪些列是程序所要的. 驱动程序只知道应用程序能请求任意的列. 当JDBC驱动程序处理 rs.next() 请求时, 它可能会跨过网络从数据库服务器至少返回一行结果. 在这种情况下, 每个结果行会包含所有的列数据– 如果Employees表有一列包含员工相片的话它也会被包含在结果里面. 限制SELECT子句的列名列表并且只包含有用的列名,会减少网络流量及更快的查询性能.
另外,虽然getClob()和getBlob()方法可以允许应用程序去如何控制获取长数据, 但开发者必须认识到在许多情况下, JDBC驱动程序缺少真正的LOB定位器的支持. 像这种情况下,在暴露getClob和getBlob方法给开发者之前驱动程序必须经过网络获取所有的长数据.
减少获取的数据量
有时必须要获取长数据. 这时, 要注意的是大多数用户并不想在屏幕上看到100k甚至更多的文字.
要减少网络交通和改善性能, 通过调用setMaxRows(), SetMaxFieldSize及SetFetchSize()方法, 你可以减少取获取的数据量. 另一种方式是减少数据的列数. 如果驱动程序允许你定义packet的大小, 使用最小的packet尺寸会适合你的需要.
记住: 要小心的返回只有你需要的行和列数据. 当你只需要2列数据而你却返回的5列数据时,性能会降低 – 特别是不需要的行中包含有长数据时.
选择合适的数据类型
接收和发送某些数据可能代价昂贵. 当你设计一个schema时, 应选择能被最有效地处理的数据类型. 例如, 整型数就比浮点数或实数处理起来要快一些. 浮点数的定义是按照数据库的内部规定的格式, 通常是一种压缩格式. 数据必须被 解压和转换到另外种格式, 这样它才能被数据的协议处理.
获取ResultSet
由于数据库系统对可滚动光标的支持有限, 许多JDBC驱动程序并没有实现可滚动光标. 除非你确信数据库支持可滚动光标的结果集, 否则不要调用rs.last()和rs.getRow()方法去找出数据集的最大行数. 因为JDBC驱动程序模拟了可滚动光标, 调用rs.last()导致了驱动程序透过网络移到了数据集的最后一行. 取而代之, 你可以用ResultSet遍历一次计数或者用SELECT查询的COUNT函数来得到数据行数.
通常情况下,请不要写那种依赖于结果集行数的代码, 因为驱动程序必须获取所有的数据集以便知道查询会返回多少行数据.
下一个月: 选用最佳性能的功能
|