在过去的30天里,我一直在开发一个Python应用程序,该应用程序利用MySQL信息数据库(特别是关于挪威地址)来执行地址验证和更正。数据库包含大约210万行(43列)数据,占用640 of的磁盘空间。
我正在考虑速度优化,并且我必须假设,当验证10,000+地址时,每次验证都会对数据库进行多达20个查询,网络是一个速度瓶颈。
我还没有做任何测量或计时,而且我确信目前有更简单的方法来优化应用程序,但我只想了解专家的意见,即在Python中将这么多数据加载到行结构中是多么的现实。还有,还会更快吗?当然,MySQL是为查找大量数据中的记录而优化的,那么删除网络步骤会有多大的帮助呢?你能想象还有什么其他可行的方法来删除网络步骤吗?
MySQL服务器的位置会有所不同,因为应用程序很可能是在本地的本地本地的笔记本电脑上运行的。
发布于 2012-12-03 12:46:43
我将避免将210万行全部加载到内存中(至少,这样做不是我的第一选择)。即使您可以使用一个查询来完成这一任务,即使您绕过了内存问题,仍然需要一段时间才能将所有数据发送给客户端。在该数据中的查找可能比通过网络进行大量SQL查询的速度更快,但如果这与初始加载相比确实有效的话(当然,您必须进行测量才能确定)。
如果我说得对,您不需要所有的数据来执行验证--您只需要10.000个地址的数据,以及一些来自可比大小的数据库的记录。我可能会尝试的是减少查询的数量,以获得准确的数据。也许你不需要每个地址20个查询,并且可以将其减少到10个?这将是一个开始。也许您可以在一个查询中获得多个地址的数据,而不是使用语句的IN或OR操作符中的WHERE子句?这可能也会有帮助,因为对于少量的数据来说,通常只有查询的数量才是关键因素,如果得到10、100或1000字节的结果集,则不是这样。
如果您需要更具体的建议,则必须提供有关数据模型和正在使用的查询的更多详细信息。
编辑:假设您的地址数据库冻结了几个月,这将有资格使用整个数据库的本地副本作为缓存。像SqlLite这样的东西应该是这里的逻辑选择:一个非常快的、没有服务器的、进程内的(和可选的内存中的)数据库,其中整个数据可以存储在一个文件中。您仍然可以对所有需要的查询使用SQL,从MySQL表到SqlLite表的转换应该非常简单(只要您目前数据库中没有使用任何特定于MySQL的东西)。
考虑一下,如果您试图将数据库表的本地副本完全保存在Python行中,取决于数据模型的复杂性,您可能最终会自己构建类似于您自己的“穷人”内存数据库。那为什么要重新发明轮子呢?
有关SqlLite Python接口的信息:http://docs.python.org/2/library/sqlite3.html。另一个优点是:如果在服务器上更新了地址数据,这种方法将或多或少地允许在服务器上创建一次数据库副本,并将数据通过网络发送到客户端。
发布于 2012-12-04 13:15:56
布朗医生的回答和梅森·惠勒的评论可能是这里最好、最实用的方法。尽管如此,这是一个有趣的概念问题,所以我倾向于评论。
还有,还会更快吗?当然,MySQL是为查找大量数据中的记录而优化的,那么删除网络步骤会有多大的帮助呢?
我们实际上是在讨论两件事:拥有数据客户端和有“自定义代码”来在数据集中进行查找。我认为这种安排的好处是:
第二点可能被用来给出您的DB的更小的表示形式。我不知道目前您的数据是如何正常化的,但是通常address倾向于在文本中包含大量的地址,然后这些地址通常会被重复多次。这不是一种非常有效的存储东西的方法,如果您的DB是这样的话,它可能可以用一个更紧凑的文件来表示(快速测试可能是对ZIP或RAR数据库进行测试,以查看其中是否存在大量的重复,尽管数据的分布可能意味着这些算法没有提供尽可能多的帮助)。此外,如果街道号码与街道名称混合为文本,我猜可以做很多工作来优化DB的索引。
TL:是的,理论上说,将数据转移到客户端可以带来一些好处。然而,实际上,您最好还是分批查询,或者使用已经发布的任何其他优秀想法。
发布于 2012-12-03 10:23:18
如果您尝试将python列表用于这类工作,您将遇到麻烦。您将有很大的内存开销,这可能会阻止您对数据做任何有用的事情。
您应该检查数组(http://docs.python.org/2/library/array.html)或是否可以numpy (http://numpy.scipy.org/)。
如果仍然无法将所有数据加载到内存中,则可以尝试按块处理数据,以限制查询的数量。
https://softwareengineering.stackexchange.com/questions/178117
复制相似问题