何时迭代一组,或何时使用数据库

时间:2015-03-09 19:11:40

标签: python mysql performance

我希望在以下情况下最大限度地提高性能:

  • 我的数据库中存储了大约1M个ID。
  • 我每天导出〜1.05M ID,我无法控制。
  • 我需要看看我有哪些物品 - 跳过那些 - 看看我没有的物品 - 添加 - 并查看哪些物品已被删除 - 修剪它们。

我应该何时使用数据库来使用它,何时应该使用它?例如,与'pass'的区别在于:

# using a set
all_ids = select id from mytable
all_ids = set(all_ids)
for item in report:
    id = item['id']
    if id in all_ids:
        pass

# using a db lookup for each item
for item in report:
    id = item['id']
    if (select 1 from mytable where id=id):
        pass

我什么时候应该使用哪个?显然,如果只有十个项目,内存列表或集合可以正常工作;另一方面,如果有1万亿个ID,我需要使用数据库查找,因为我本地没有足够的内存。我该如何做出这个决定?

1 个答案:

答案 0 :(得分:1)

为了避免应用程序内存不足,让数据库进行搜索,这是它擅长的。我假设你有id索引。

SELECT使用准备好的(参数化的)查询。准备好的查询只需要解析一次,然后从那时开始,参数通过有效的二进制协议发送。这节省了大量开销(您不会将整个查询发送到每行的数据库服务器)。

标准Python可能不支持准备好的查询,因此您可能必须使用oursql中提到的Does the MySQLdb module support prepared statements?等第三方库。

MySQL内置了优化功能,可以在读取多个连续页面时在磁盘上提前读取,从而可以利用现在也可以读取的现代磁盘缓存。事实上,如果你的服务器有足够的内存使整个索引保留在内存中,MySQL可能根本就不会遇到磁盘。此外,一个查询消除了发送一百万个命令并等待应用程序和数据库服务器之间的响应所能获得的所有网络开销和延迟。因此,虽然MySQL能够更有效地同时为您提供所有数据,但您仍然会为所有设置条目分配内存,搜索应用程序中的集合以及可能耗尽记忆。

即使您一次读取所有数据,默认情况下您可能会使用缓冲查询,因此结果将保留在内存中,直到您无论如何都要读取它为止。无缓冲的查询会使问题复杂化。