我有一张桌子tmp_drop_ids
用一列,id
,以及 330 万个条目。我想迭代该表,每 200 个条目执行一些操作。我有这个代码:
LIMIT = 200
for offset in xrange(0, drop_count+LIMIT, LIMIT):
print "Making tmp table with ids %s to %s/%s" % (offset, offset+LIMIT, drop_count)
query = """DROP TABLE IF EXISTS tmp_cur_drop_ids; CREATE TABLE tmp_cur_drop_ids AS
SELECT id FROM tmp_drop_ids ORDER BY id OFFSET %s LIMIT %s;""" % (offset, LIMIT)
cursor.execute(query)
一开始运行得很好(大约 0.15 秒生成 tmp 表),但偶尔会变慢,例如大约 300k 票证开始需要 11-12 秒来生成此 tmp 表,然后再次大约 400k。基本上看起来不可靠。
我将在其他查询中使用这些 id,因此我认为放置它们的最佳位置是在 tmp 表中。有没有更好的方法来迭代这样的结果?
请改用光标。使用 OFFSET 和 LIMIT 非常昂贵 - 因为 pg 必须执行查询、处理和跳过 OFFSET 行。 OFFSET 就像“跳过行”,这是昂贵的。
光标文档 http://www.postgresql.org/docs/9.1/static/sql-declare.html
游标允许对一个查询进行迭代。
BEGIN
DECLARE C CURSOR FOR SELECT * FROM big_table;
FETCH 300 FROM C; -- get 300 rows
FETCH 300 FROM C; -- get 300 rows
...
COMMIT;
也许您可以使用服务器端游标,而无需显式使用 DECLARE 语句,只需支持psycopg http://initd.org/psycopg/docs/usage.html(有关服务器端光标的搜索部分)。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)