I';m正在编辑一个从数据库加载数据的应用程序,但它在继续运行时运行速度较慢
本文关键字:应用程序 数据 继续 速度 运行 运行时 加载 编辑 一个 数据库 | 更新日期: 2023-09-27 18:24:47
它不是一个设计良好的应用程序,但它完成了任务,因此得到了使用。在过去的一周里,我一直在对它进行修改。我添加和删除了一些功能。它从SQL表中获取数据。根据运行情况,有时此数据可能超过20000行!
我想让它一次只加载大约500行到应用程序中,因为当只有500行要处理时,它需要几秒钟,而不是几分钟。我正在与pdf合作,这可能也是问题的一部分,但我认为这应该不会太难实现。
但问题是,我不确定如何实现它。我的想法是将查询从0限制到500,然后增加这个限制。但是,主循环检查返回的行是否为null。我如何知道返回的行是否为空,因为它是表的最后一行,而不是块的最后一行将返回?
编辑:我道歉。查询很快。然而,在我对pdf文件进行操作的过程中,这些操作的速度会变慢,pdf文件存储在应用程序运行的文件系统上。我在想,我将20000行数据拉入应用程序,并让它在本地循环,这会导致速度减慢。我可能错了,但这就是我想要实现分页的原因。只在500行上运行程序非常快。它们都在程序开始时拉入所有行,然后使用库对PDF执行操作(即将该行数据放在页面上)。每一行对应于PDF中的一个页面,因此PDF变得如此之大的事实可能也会减慢速度,但我会开始分页工作,然后再报告。随着时间的推移,这更像是一个应用程序性能问题。
由于信息有限,我只能参考一些好的SQL分页资源,这是开发人员非常常用的限制检索记录数量的技术。
你可以在网上找到大量的帖子。。这是其中一个。
您可以在查询不再返回500个元素时立即设置一个标志,并在主循环条件中检查该标志。
YOu总是可以获取一个完整的密钥集,然后您的客户端可以通过将密钥集的子集传递给存储过程来获取您需要的行的子集(第一组500、第二组500、第一组500等),存储过程可以从这些密钥创建一个表并进行内部联接。
Oops。我没有仔细阅读这个问题。以下是基于错误读取,即单个PDF存储在数据库中。如果没有从数据库中提取大量数据,请忽略此答案,因为速度缓慢可能是由PDF生成器本身造成的,并且可以通过"注释掉添加页面"轻松验证。2万个合理大小的记录算不了什么。
但问题是,我不确定如何实现它。我的想法是将查询从0限制到500,然后增加这个限制。
嗯,有点(忽略可能添加的新记录或删除的记录)。
以下是一种通用方法的步骤。(这不是唯一的方法,但我强调它,因为它是问题中提出的方法的变体,并解决了上述问题。)
- 对数据进行排序(使用视图操作时始终如此!)
- 使用在RDBMS中实现的LIMIT和OFFSET。如果不使用偏移,则LIMIT增加实际上是无用的
- 查询时,每个补丁最多限制一行如果你收回LIMIT行,你就完了。如果返回LIMIT+1行,则需要发出另一个获取,因为有更多的记录
- 将OFFSET增加LIMIT并循环直到完成
在SQL Server中使用OFFSET。。获取。。按排序
如果在此过程中可以添加/删除行,则需要考虑其他因素,以避免幻影记录和重复记录处理。如果这样的问题是一个问题,而且可能应该是,为了简单起见,我鼓励禁止这样的操作,即在整个循环过程中使用SERIALIZABLE事务。
分页的另一种选择(实际上,20k条记录非常少)是仅根据需要加载/使用较大的"PDF"/BLOB列,以降低内存压力。使用内存并不一定是坏事:但如果将分配推送到交换或丢弃热缓冲区,则可能会对性能产生严重影响。
由于我们谈论的是SQL Server,因此可以使用较新的FILESTREAM类型来代替BLOB来存储PDF数据。对于FILESTREAM列,SqlDataReader最初不会读取整个文件/流,而只获取"文件指针"。然后,可以在每个项目的基础上获得基础文件。
这种方法也可以通过正常的BLOB存储和仔细选择记录(例如,在处理特定记录时只获取"PDF"/BBLOB)或通过文件系统等外部存储(例如,只将"文件路径"存储在数据库中)来模拟。
由于并非总是加载所有数据,因此使用延迟加载大型二进制/BLOB数据的方法应该可以减轻观察到的性能影响(如果它确实与内存压力有关),并更好地扩展(尽管是一个常数):在这种情况下,它可以完全消除分页的需要。