1

我有一个有几亿行的 sqlite 表:

sqlite> create table t1(id INTEGER PRIMARY KEY,stuff TEXT );

我需要通过它的整数主键来查询这个表数亿次。我的代码:

conn = sqlite3.connect('stuff.db')
with conn:
    cur = conn.cursor()
    for id in ids:
        try:
            cur.execute("select stuff from t1 where rowid=?",[id])
            stuff_tuple = cur.fetchone()
            #do something with the fetched row
        except:
            pass #for when id is not in t1's key set

在这里,ids 是一个可能包含数万个元素的列表。形成 t1 并没有花费很长时间(即每秒插入约 75K 次)。以我的方式查询 t1 速度慢得令人无法接受(即 10 秒内约 1K 次查询)。

我对 SQL 完全陌生。我究竟做错了什么?

4

2 回答 2

1

由于您通过键检索值,因此在这种情况下,键/值存储似乎更合适。关系数据库(包括 Sqlite)绝对是功能丰富的,但您无法击败简单的键/值存储的性能。

有几种可供选择:

  • Redis:“高级键值存储”,非常快,针对内存操作进行了优化
  • Cassandra:极高的性能、可扩展性,被多个知名站点使用
  • MongoDB:功能丰富,试图成为关系和 NoSQL 之间的“中间地带”(他们已经开始提供免费的在线课程

还有很多很多

于 2012-11-20T06:26:12.390 回答
0

您应该改为进行一次 sql 调用,应该更快

conn = sqlite3.connect('stuff.db')
with conn:
    cur = conn.cursor()

    for row in cur.execute("SELECT stuff FROM t1 WHERE rowid IN (%s)" % ','.join('?'*len(ids)), ids):
        #do something with the fetched row
        pass 

您不需要尝试,除非数据库中没有的 id 不会显示。如果您想知道结果中没有哪些 id,您可以执行以下操作:

ids_res = set()
for row in c.execute(...):
    ids_res.add(row['id'])
ids_not_found = ids_res.symmetric_difference(ids)
于 2012-10-25T04:08:47.513 回答