【问题标题】:get n records at a time from a temporary table从临时表中一次获取 n 条记录
【发布时间】:2010-06-17 21:34:54
【问题描述】:

我有一个包含大约 100 万个条目的临时表。临时表存储较大查询的结果。例如,我想一次处理 1000 条记录。设置查询以使我获得前 1000 行,然后是下 1000 行等的最佳方法是什么?它们本质上不是有序的,但临时表只有一列带有 ID,因此我可以在必要时对其进行排序。我正在考虑使用临时表创建一个额外的列来对所有行进行编号,例如:

CREATE TEMP TABLE tmptmp AS
SELECT ##autonumber somehow##, id
FROM .... --complicated query

那我可以做:

SELECT * FROM tmptmp WHERE autonumber>=0 AND autonumber < 1000

等等...我将如何真正做到这一点?或者,还有更好的方法?我正在使用 Python 和 PostgreSQL。

【问题讨论】:

  • 您可以指定您使用的是pygresql 还是psycopg2...
  • 如果您要创建一个包含一百万行的临时表,可能会有更好的方法,但如果不知道这些表以及您试图实现的结果,就很难说...
  • 尝试使用 Postgres 游标和 LIMIT start, size。如果你愿意,我可以详细说明。

标签: python sql database postgresql


【解决方案1】:

使用游标并获取所需的行。当你有很多记录时,偏移量...限制会变慢,游标会做得更好。

http://www.postgresql.org/docs/8.4/interactive/sql-fetch.html

【讨论】:

  • 当然。从 Python 中我只需要做 cur.fetchmany(1000) 而不是 cur.fetchall() 嘿。
  • +1 是的,这当然是更好的解决方案(很快就会删除我的)。在 Python 中符合 dbapi2 的数据库接口中,您确实会使用 std .execute(sql) 后跟一系列 .fetchmany(1000) 直到光标完全消耗。
【解决方案2】:

也许您可以使用这样的东西(我们在批量更新具有 +2000 万行的表并且不想占用复制时使用)。

import sys
import psycopg2
from datetime import datetime

firstid = 0
splitsize = 50 # Size of each batch


# Complicated query
query_complex = """
    CREATE TEMP TABLE tmptmp AS
    SELECT * FROM schema.massive_table
"""
# Query to be run at intervals
query = """
    SELECT * FROM tmptmp WHERE id BETWEEN %(startid)s AND %(endid)s
"""

conn = psycopg2.connect("dbname=database_name user=postgres")
curs = conn.cursor()
# Run complicated query
curs.execute(query_complex)
# Get highest id
curs.execute("SELECT max(id) FROM tmptmp")
maxid = curs.fetchall()[0][0]
print "Max id: %s" % maxid

for startid in range(firstid, maxid, splitsize):
    endid = startid + splitsize - 1
    print "%s: Running query on range %s to %s" % (datetime.now(), startid, endid)
    curs.execute(query, {'startid':startid, 'endid':endid})
    print "%s: Affected rows: %s. Total completed: %s%%" % (datetime.now(), curs.rowcount, round((endid * 100) / maxid, 3))

print "Done."

以下输出:

Max id: 308
2010-06-18 11:59:11.271000: Running query on range 0 to 49
2010-06-18 11:59:11.271000: Affected rows: 49. Total completed: 15.0%
2010-06-18 11:59:11.271000: Running query on range 50 to 99
2010-06-18 11:59:11.271000: Affected rows: 50. Total completed: 32.0%
2010-06-18 11:59:11.271000: Running query on range 100 to 149
2010-06-18 11:59:11.271000: Affected rows: 50. Total completed: 48.0%
2010-06-18 11:59:11.271000: Running query on range 150 to 199
2010-06-18 11:59:11.271000: Affected rows: 49. Total completed: 64.0%
2010-06-18 11:59:11.271000: Running query on range 200 to 249
2010-06-18 11:59:11.271000: Affected rows: 42. Total completed: 80.0%
2010-06-18 11:59:11.271000: Running query on range 250 to 299
2010-06-18 11:59:11.318000: Affected rows: 3. Total completed: 97.0%
2010-06-18 11:59:11.318000: Running query on range 300 to 349
2010-06-18 11:59:11.318000: Affected rows: 1. Total completed: 113.0%
Done.

// 约翰

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-18
    相关资源
    最近更新 更多