Ank*_*kit 1 c# ms-access network-share
我有一个使用MS Access数据库(.mdb文件)的C#应用程序.我与网络用户共享我的数据库,以便他们可以使用我的应用程序访问数据库.
当我运行我的应用程序时,在网络数据库上执行查询需要更长的时间,而同一查询在本地计算机上花费的时间更少.
任何人都可以提供有关如何通过网络共享上的Access数据库减少此性能问题的建议吗?
当然,通过网络访问数据库的查询不会像访问本地硬盘驱动器上的数据库那样快.不幸的是,开发人员构建一个在本地运行良好的应用程序是相当普遍的,但一旦在网络上部署就会显着减慢.(对于任何开发人员都是如此,而不仅仅是使用Access数据库的开发人员.)
根据我的经验,使用共享Access数据库执行应用程序性能的三个最重要的事情是:
表扫描是像Access这样的共享文件数据库上的谋杀案.确保在WHERE子句中使用的字段上具有索引,或者用于JOIN表.
为了说明,我在122 MB .accdb文件上运行以下命令,该文件包含一个包含421,184行的表:
cmd.CommandText =
"SELECT COUNT(*) AS n FROM zz_sys_archive " +
"WHERE archived Between #2013-01-01# And #2013-04-01#";
Run Code Online (Sandbox Code Playgroud)
如果[archived]字段没有索引,则该命令需要78秒才能执行并生成107 MB的网络流量.
向[archived]字段添加索引后,该命令需要0.4秒才能执行并生成0.9 MB的网络流量.
(但是,不要疯狂并索引所有内容,因为无关的索引只会降低INSERT和UPDATE操作的速度.)
即使使用适当的索引,设计不良的查询也会导致表扫描并降低应用程序的速度.例如,查询
cmd.CommandText =
"SELECT COUNT(*) AS n FROM zz_sys_archive " +
"WHERE Year(archived) = 2013";
Run Code Online (Sandbox Code Playgroud)
不是sargable,这意味着它不能使用[archived]字段上的索引并使用与之前相同的结果进行表扫描(约80秒完成).但是,等效查询
cmd.CommandText =
"SELECT COUNT(*) AS n FROM zz_sys_archive " +
"WHERE archived >= #2013-01-01# AND archived < #2014-01-01#";
Run Code Online (Sandbox Code Playgroud)
执行大约一秒钟.
使用本地数据库,通常只是阅读整个表并忽略您不想要的内容.通过网络访问数据库会使代价变得更加昂贵,因此在"SELECT*FROM"之前,请考虑一下您真正需要的内容.