postgresql:offset + limit变得非常慢

Cla*_*diu 5 sql postgresql performance limit offset

我有一个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)
Run Code Online (Sandbox Code Playgroud)

一开始运行良好(〜0.15s生成tmp表),但它会偶尔减速,例如大约300k票据开始需要11-12秒生成这个tmp表,再次大约400k.它基本上似乎不可靠.

我将在其他查询中使用这些ID,因此我认为将它们放在tmp表中的最佳位置.有没有更好的方法来迭代这样的结果?

Pav*_*ule 10

请改用光标.使用OFFSET和LIMIT非常昂贵 - 因为pg必须执行查询,处理和跳过OFFSET行.OFFSET就像"跳过行",这很昂贵.

游标文档

游标允许对一个查询进行迭代.

BEGIN
DECLARE C CURSOR FOR SELECT * FROM big_table;
FETCH 300 FROM C; -- get 300 rows
FETCH 300 FROM C; -- get 300 rows
...
COMMIT;
Run Code Online (Sandbox Code Playgroud)

可能你可以在没有明确使用DECLARE语句的情况下使用服务器端游标,只需支持psycopg(关于服务器端游标的搜索部分).