程序员之家 >> 文章 >> Java技术 >> 数据库持久层
持久层设计和数据库设计的原则
作者:   来源:http://www.diybl.com/course/3_program/java/javajs/20071022/79417.html   发布者:admin
时间:2009-04-17 17:44:57   点击:1693

        持久层设计在决定使用数据库的性能方面起关键作用。持久层确定查询类型、何时提交查询以及如何处理查询结果。这反过来对服务器上的锁类型和持续时间、I/O 活动量以及处理 (CPU) 负荷等产生主要影响,并由此影响总体性能的优劣。

        正因为如此,在持久层的设计阶段做出正确决策十分重要。然而,即使在使用总控应用程序时(这种情况下似乎不可能更改持久层应用程序)出现性能问题,也不会改变影响性能的根本因素:持久层具有支配作用,如果不更改持久层则许多性能问题都无法解决。设计优秀的持久层允许数据库支持成千上万的并发用户。反之,设计差的持久层会防碍即使是最强大的服务器平台处理少数用户的请求。

持久层应用程序的设计准则包括:

消除过多的网络流量。

        持久层和数据库之间的网络往返通常是数据库应用程序性能较差的首要原因,甚至超过了服务器和持久层之间传送的数据量这一因素的影响。网络往返描述在持久层应用程序和数据库之间为每个批处理和结果集发送的会话流量。通过使用存储过程,可以将网络往返减到最小。例如,如果应用程序根据从数据库收到的数据值采取不同的操作,只要可能就应直接在存储过程中做出决定,从而消除过多的网络流量。

        如果存储过程中有多个语句,则默认情况下,数据库在每个语句完成时给持久层应用程序发送一条消息,详细说明每个语句所影响的行数。大多数应用程序不需要这些消息。如果确信应用程序不需要它们,可以禁用这些消息,以提高慢速网络的性能。请使用 SET NOCOUNT 会话设置为应用程序禁用这些消息。

使用小结果集。

        检索没必要大的结果集(如包含上千行)并在持久层浏览将增加 CPU 和网络 I/O 的负载,使应用程序的远程使用能力降低并限制多用户可伸缩性。最好将应用程序设计为提示用户输入足够的信息,以便查询提交后生成大小适中的结果集。

        可帮助实现上述目标的应用程序设计技术包括:在生成查询时对通配符进行控制,强制某些输入字段,不允许特殊查询,以及使用 TOP,PERCENT 或 SET ROWCOUNT 等 Transact-SQL 语句限制查询返回的行数。允许在用户需要重新控制应用程序时取消正在执行的查询。

        应用程序决不应强迫用户重新启动客户机以取消查询。无视这一点将导致无法解决的性能问题。如果应用程序取消查询(例如使用开放式数据库连接 (ODBC) sqlcancel 函数取消查询),应对事务级别予以适当的考虑。例如,取消查询并不会提交或回滚用户定义的事务。取消查询后,所有在事务内获取的锁都将保留。因此,在取消查询后始终要提交或回滚事务。
始终实现查询或锁定超时。

        不要让查询无限期运行。调用适当的 API 以设置查询超时。例如,使用 ODBC SQLSetStmtOption 函数。

        不要使用不允许显式控制发送到数据库的 SQL 语句的应用程序开发工具。 如果工具基于更高级的对象透明地生成 Transact-SQL 语句,而且不提供诸如查询取消、查询超时和完全事务控制等关键功能,则不要使用这类工具。如果应用程序生成透明的 SQL 语句,通常不可能维护好的性能或解决性能问题,因为在这种情况下不允许对事务和锁定问题进行显式控制,而这一点对性能状况至关重要。 只在必要时才使用游标。

        游标是关系数据库中的有用工具,但使用游标完成任务始终比使用面向集合的 SQL 语句花费多。

        当使用面向集合的 SQL 语句时,持久层应用程序让服务器更新满足指定条件的记录集。服务器决定如何作为单个工作单元完成更新。当通过游标更新时,持久层应用程序要求服务器为每行维护行锁或版本信息,而这只是为了持久层在提取行后请求更新行。

        而且,使用游标意味着服务器通常要在临时存储中维护持久层的状态信息,如用户在服务器上的当前行集。为众多持久层维护这类状态信息需消耗大量的服务器资源。对于关系数据库,更好的策略是让持久层应用程序快速进出,以便在各次调用之间不在服务器上维护持久层的状态信息。面向集合的 SQL 语句支持此策略。

        然而,如果查询使用游标,请确定如果使用更高效的游标类型(如快速只进游标)或单个查询能否更高效地编写游标查询。使事务尽可能简短。 使用存储过程。 使用 Prepared Execution 来执行参数化 SQL 语句。 始终处理完所有结果。

        不要设计或使用在未取消查询时就停止处理结果行的应用程序。否则通常会导致阻塞和降低性能。确保将应用程序设计为可避免死锁。 确保已设置所有能够优化分布式查询性能的适当选项

最新文章
点击排行