2010-08-04 74 views
2

可以说我有一个数据库表,它由三列组成:id,field1field2。这张表可能有100到100000行之间的任何地方。我有一个python脚本,应该在此表中插入10-1,000个新行。但是,如果表中已存在新的field1,它应该执行UPDATE,而不是INSERTPython性能:搜索大列表vs sqlite

以下哪种方法更有效?

  1. 做一个SELECT field1 FROM tablefield1是唯一的),并将其存储在列表中。然后,对于每个新行,请使用list.count()来确定是INSERT还是UPDATE
  2. 对于每一行,运行两个查询。首先,SELECT count(*) FROM table WHERE field1="foo"然后是INSERTUPDATE

换句话说,执行n + 1个查询和搜索列表,或者2n个查询并获得sqlite搜索效率更高吗?

+0

我不确定我是否理解“计数”的必要性 - 您究竟计算了什么?你只需要检查存在,对吧? (因为每个'field1'值只能有一个..) – tzaman 2010-08-04 10:30:22

+0

好点,我想它可以简化为'SELECT 1 FOM table WHERE field1 =“foo”'。 – 2010-08-04 13:51:12

回答

9

如果我正确理解你的问题,它似乎可以简单地使用SQLite内置的冲突处理机制。

假设您有field1的UNIQUE约束,你可以简单的使用:

INSERT OR REPLACE INTO table VALUES (...) 

下面的语法还支持(相同的语义):

REPLACE INTO table VALUES (...) 

编辑:我知道我是没有真正回答你的问题,只是提供一个更快的替代解决方案。

+0

+1,我正要发布这个自己。 – tzaman 2010-08-04 10:35:20

+0

很酷,谢谢!虚拟+1,我今天没票了。叹息:) – sarnold 2010-08-04 10:43:21

+0

很好的答案!伟大的功能。令人遗憾的是它不在SQL-92规范中,所以* all * RLDB的实现:) – invert 2010-08-04 11:29:49

0

我想象一下,使用python字典可以比使用python列表更快地进行搜索。 (只需将值设置为0,您不需要它们,并希望'0'存储紧凑。)

至于更大的问题,我也很好奇。 :)

+2

或者只是将它们存储在'set'而不是'dict'中... – tzaman 2010-08-04 10:29:09

+0

感谢tzaman,没有意识到集合是快速的:) – sarnold 2010-08-04 10:42:46

1

我不熟悉的源码,但像这样的一般方法应该工作:

如果有上field1唯一索引,并且你要插入一个值已经存在,你应该得到一个错误。如果插入失败,则使用更新。

伪代码:

try 
{ 
    insert into table (value1, value2) 
} 
catch(insert fails) 
{ 
    update table set field2=value2 where field1=value1 
} 
0

你似乎与橘子进行比较苹果。

只有当您的数据符合进程的地址空间时,python列表才有用。一旦数据变大,这将不再起作用。

此外,python列表没有编入索引 - 因为你应该使用字典。

最后,python列表是非持久性的 - 当进程退出时它会被遗忘。

你怎么能比较这些?