解析大型XML提要时处理重复数据

解析大型XML提要时处理重复数据,xml,feed,polling,feedparser,stockquotes,Xml,Feed,Polling,Feedparser,Stockquotes,我正在编写一个组件,它解析带有股票报价的xml提要,并将结果保存到数据库中。问题相当简单,只是提要不能增量读取。也就是说,没有办法指定您只希望更改X最后一个引号,或者仅更改比X分钟更新的引号。我知道真正的问题是feed很愚蠢,提供者应该修复他们的东西,但这不是一个选项 该提要是一个巨大的xml文件,其中包含提供商最后100000个股票报价。该提要每分钟轮询一次,在此期间大约有50-100个已更改的报价。其余的是重复的引号,它们被反复读取 在提要的每次轮询期间,我将所有引号(使用lxml)解析为对

我正在编写一个组件,它解析带有股票报价的xml提要,并将结果保存到数据库中。问题相当简单,只是提要不能增量读取。也就是说,没有办法指定您只希望更改X最后一个引号,或者仅更改比X分钟更新的引号。我知道真正的问题是feed很愚蠢,提供者应该修复他们的东西,但这不是一个选项

该提要是一个巨大的xml文件,其中包含提供商最后100000个股票报价。该提要每分钟轮询一次,在此期间大约有50-100个已更改的报价。其余的是重复的引号,它们被反复读取

在提要的每次轮询期间,我将所有引号(使用lxml)解析为对象。然后,对于每个quote对象,我检查数据库中是否已经存在quote。如果有,我丢弃它,如果没有,我保存它。这个过程非常浪费,因为只有大约0.1%是新数据,其余都是重复数据。为了稍微优化一下,我创建了一个查找表,通过查询数据库一次,查找在过去X小时内更新的引号。在数据库中(last_update,stock_id)键上的引号是唯一的,因此此优化将查询数量减少约50%

但是仍然有50k db查询,其中每个报价都必须单独检查是否存在,这对数据库来说是非常费力的


所以我要寻找的是如何使我的提要解析器更快的想法。也许有一种方法可以将最后获取的xml文件与新文件区分开来

最近的项目是在提要的顶部还是底部?如果它们位于顶部,那么当您看到第一个已经存在于 数据库


如果最近的项目最后出现,您可以缓存引号键,只需在内存中查找它们,一旦找到未缓存的项目,就开始访问数据库。或者,您可以记住在数据库中输入的最后一个引号,并且在解析所有项目时查找它,并且只在数据库中查找后面的项目。

您的问题分为两个方面:1)如何避免解析不需要解析的内容,以及2)如何避免不需要解析的数据库操作

如果引号本身很小,您可能不会从尝试求解(1)中获得太多好处。否则,您可以创建一个过滤器(例如使用XSLT或SAX),该过滤器将丢弃您不关心的引号,然后对其余部分执行完整的DOM解析

要解决(2),区分XML文件通常是很棘手的,因为XML文档中的空白更改(在某些提供者中非常常见)可能会导致误报,并且您通常需要分析实际XML结构的内容,而不是简单的文本逐行区分。如果您不认为这对您来说是个问题,您可以探讨几个堆栈溢出主题,但我认为它们也将证明XML差异仍然是一个有点模糊的领域,特别是在开源领域:

另一种可行的方法是使用本地或分布式内存缓存来快速查找已经更新的内容。您将获得避免尝试过滤或区分内容的好处,并且如果您正在构建一个长期的基础架构,那么您可以很容易地为其他用例调整缓存基础架构。OTOH,创建一个可伸缩的分布式缓存基础设施并不是一个特别便宜的解决方案