总的考虑方向
) 根据数据使用的方式来设计数据访问层
) 缓存数据避免不必要的操作
) 使用服务帐户进行连接
) 必要时连接尽早释放
) 关闭可关闭的资源
) 减少往返
) 仅返回需要的数据
) 选择适当的事务类型
) 使用存储过程
根据性能维护性及实现难度来决定跨层数据传递的方式
具体实现
)选用合适的Data Provider
应尽量使用专用的Data Provider下面是一个性能比较表
可以看出SqlClient的速度是最快的其主要原因是其他的数据提供者都经过的几个层次的转换
可以看出SqlClient直接访问DB Netlib而其他的数据提供者都经过了两层转换因此在设计多层应用的时候并不是层次越多越好而是应该在可扩展性与性能间取折中增加层次是会降低性能的
) 数据库连接
i 在方法中打开和关闭连接即不要在类的构造函数中打开连接在类的析构函数中关闭连接
ii 使用完连接明确地关闭因为有连接池的支持关闭连接只是将连接放回连接池并不是真正销毁不会带来性能开销而会增加连接池中可用连接提升性能
iii 当使用DataReaders时指定CommandBehaviorCloseConnection
iv 当使用Fill()与Updata()时不要手动打开连接因为DataAdapter会自动开启连接但是如果是Command则需要手动开启
v 避免检查OleDbConnection的State属性其性能开销相当大
vi 使用连接池这种方法可以大幅度提高性能默认的情况下通过SqlClient连接数据库时会使用连接池另可以通过连接字符串来控制连接池的最大值最小值以及是否开启连接池
) SQL指令
i 检查SQL的输入并使用参数直接使用字符连接容易遭受注入式攻击
ii 仅返回需要的行和例
iii 对大的数据集使用分页功能
iv 批次执行SQL避免多次往返
v 如果没有数据返回则使用ExecuteNonQuery方法
vi 当返回一个标量时使用ExecuteScalar方法
vii 不要在运行时间使用CommandBuilder尽管很省事但是开销很大
) 存储过程
i 尽量使用存储过程
ii 对于OleDbCommand指令类型为CommandTypeText
iii 使用SqlCommand指令类型为CommandTypeStoredProcedure
iv 尽可能使用输出参数
v 考虑在SQL Server中SET NOCOUNT ON即关闭SQL Server的记数功能
) 事务
) 使用参数
i 在存储过程上使用参数
ii 创建参数并指定类型
iii 可将参数对象进行缓存
) DataReader和DataSet
i DataReader对象需要关闭
ii 用DataReader时应使用CommandBehaviorCloseConnection关闭连接
iii DataReader应用在只读只向前翻滚的数据访问场景
iv 只想快速访问数据不需要缓存功能应使用DataReader
DataSet在需要数据缓存并在不同层间传递时使用它可以存放多个结果集可以在离线的情况下自由定位查找数据
总的来说提高性能会降低可扩展性以及维护难度应在满足功能与非功能需求的情况下提高性能